chrisyip
chrisyip
Chris's Blog
67 posts
Don't wanna be here? Send us removal request.
chrisyip · 6 years ago
Text
为 docker-machine env 提速
今天因钉钉出了问题,无法退出,在 Activity Monitor 里也没有看到进程,只好强制重启 macOS,但在重启后 docker machine 就异常了:machine 连接超时,也不能 stop machine。由于我手滑把唯一一个有报错信息的 shell 给关了,只能 Google 一下看看有没有解决方法,在搜索的过程中意外发现了提高 docker-machine env 的速度的方法:
$(docker-machine inspect ${DOCKER_MACHINE_NAME} --format \ "export DOCKER_HOST=tcp://{{ .Driver.IPAddress }}:2376 export DOCKER_TLS_VERIFY=1 export DOCKER_CERT_PATH={{ .HostOptions.AuthOptions.StorePath }} export DOCKER_MACHINE_NAME=${DOCKER_MACHINE_NAME}"
我平时习惯用多个 iTerm window 来跑不同服务,为了减少 eval $(docker-machine env MACHINE) 的次数,就直接把启动 docker 的脚本写到了 .zshrc 里,但 docker-machine env 会影响到 shell 的打开速度,在根据上面的方法修改了启动脚本后,打开新 shell 几乎秒开,有需要的朋友可以参考改一下:
# 要启动的 machine DOCKER_MACHINE_NAME=default # 因为 docker-machine 会忽略已启动的 machine 而不会报错,省掉判断的工作 docker-machine start ${DOCKER_MACHINE_NAME} &> /dev/null # 设置环境变量 eval $(docker-machine inspect ${DOCKER_MACHINE_NAME} --format \ "export DOCKER_HOST=tcp://{{ .Driver.IPAddress }}:2376 export DOCKER_TLS_VERIFY=1 export DOCKER_CERT_PATH={{ .HostOptions.AuthOptions.StorePath }} export DOCKER_MACHINE_NAME=${DOCKER_MACHINE_NAME}") # 对此 machine 的请求不使用 proxy,不需要的可以不加 export NO_PROXY=$(echo $DOCKER_HOST | sed 's/tcp:\/\/\([^:]*\).*/\1/')
至于我遇到 machine 连接问题,在再次重启 macOS 后就正常了。
0 notes
chrisyip · 8 years ago
Text
关于 “Cannot find module '../build/Release/NAME.node'”
如果 node 项目启动时遇到 Cannot find module '../build/Release/NAME.node' 的错误,说明当前使用的 node 并不是 Release build,区分是不是 Release build 可以通过这条命令来判断:
node -e "console.log(process.config.target_defaults.default_configuration)"
如果是通过 Homebrew 安装的,那基本上都是 Debug build,而通过 nvm 安装的都是 Release build,所以遇到这个问题要么重装一次 node 要么改用 nvm 安装的版本。
如果你是 native module 的作者的话,可以试试这么干:
try { module = require('/path/to/release/build') } catch (e) { module = require('/path/to/debug/build') }
这样能少一些麻烦,虽然生产环境的话都应该使用 Release build。
0 notes
chrisyip · 9 years ago
Text
Unpack .pkg and get .app
Some apps only provide .pkg file, it’s unneccessary and less secure, here’s how to get .app from .pkg directly:
$ pkgutil --expand path/to/.pkg path/to/save/unpacked $ cd path/to/save/unpacked
Now you will get something like this:
$ ls Distribution Resources   APP_NAME.pkg
Then:
$ tar xvf APP_NAME.pkg/Payload $ ls APP_NAME.app Distribution   Resources   APP_NAME.pkg
Done!
0 notes
chrisyip · 9 years ago
Text
《うちの娘の為ならば、俺はもしかしたら魔王も倒せるかもしれない。》
最近把《うちの娘の為ならば、俺はもしかしたら魔王も倒せるかもしれない。》 (中译:为了女儿我说不定连魔王都能干掉) 五卷看完了。
起初是因为这一部漫画里的萌萝莉而去看的:
Tumblr media
第一二卷还算不错,但后几卷就差强人意,不知道是作者江郎才尽还是迫于人气压力想草草结尾。
总体评价 3/5,要看的话,可以先看看はた。画的漫画。
以下内容包含剧透,请注意。
剧情简介:身为冒险者的人类族男主角,而女主角是被驱逐出出生地的魔人族。在女主角因和她一起的父亲受伤死去而陷入困境时,与男主角相遇,并以养女身份被带了回男主角生活的人类城镇。在他们共同生活到女主角成年的时候,因为女主角被驱逐的原因,男主角开始讨伐魔王之旅,拯救了女主角。
前两卷主要描写���人的日常生活,和《白兔糖》类似,女主角的性格设定也相当讨人喜欢,当作悠闲读物来读的话,是不错的。
问题在于女主角身世这一个设定上,在解释女主角的设定前先说一下这部作品的世界观。
书中世界是比较常见的以欧洲中世纪为基础的魔幻世界,常见的魔法、神、魔王、勇者、人族 (人类族、巨人族、魔人族等) 、魔兽、幻兽等设定都有,其中有几个关键设定。
世界之理:神是作为世界规则的制定者和维护者存在,不能直接干涉世界,而会通过加护的形式对世界进行干涉。世界上有多个神,各司其职,不会相互干涉,比如掌管商业的神,在受到自己加护的对象在交易中进行了欺诈等行为时会下达神罚 (收回加护) ,而对加护对象的其他行为视若无睹。
神的加护:加护有各种类型,只能由神所授予,大体上类似 RPG 游戏的天赋设定,比如掌管军事的神赋予的加护会极大强化军事或战斗方面的能力。加护也有强弱之分。一般而言,每人只会得到一个神的加护,而且多数只会得到一种加护,而特殊的人可以获得来自一个或多个神的多重加护。
魔王:魔王并不是和神相对的存在,反而是神的代理人,并且具有神的部分能力,类似半神的存在 (日本常见的神之末尾的身份) 。上述有提到,神对世界的干涉是通过制订规则和加护进行间接干涉,即使是神罚,也只是收回加护的程度,而魔王则是神可以对世界进行直接的物理性的干涉的工具。因此,魔王是经由神对其赋予特殊的加护而诞生的,而且除勇者和魔王外,是不可能被杀死,也没有寿命限制。魔王只会在魔人族中诞生。
七大魔王:魔王总数为八,但被人所熟知的且活跃在世界舞台的是七大魔王 (一之七) ,每个魔王都有各自擅长的领域,比如作为王进行国家统治、散播疾病、杀戮狂魔等等。
八之魔王:神用来限制魔王的工具,七大魔王同时现世时,八之魔王亦会现世。八之魔王出现时,其他的魔王的无限寿命加护将会消息,魔力也会开始流失,慢慢步向死亡。
勇者:神用来限制魔王的工具,并没有神的能力,只是战斗能力被强化,且可以抵消魔王不会死亡的加护效果。
以上几个设定构成了「为了女儿,干掉魔王」这一故事的前提,但从以上设定来看,可以看出���不少不协调之处:
对抗魔王的派别过于弱小,魔王也是有眷属和自己的领土,而勇者和魔王相比也只是战斗能力被强化的人族,且魔王可以同时存在八位,勇者可能只会有一个,以一敌八,战斗能力也无法和魔王并驾齐驱。
魔王的存在很怪异,符合魔王设定的只有二之魔王、四之魔王:二是杀戮狂魔,连一之魔王也杀了;四是散播疾病瘟疫。其他魔王:一是正常的国家统治者;三带领族人和其他人族共同生活;五只是一个家里蹲书呆子;六是以游牧为主的巨人族统治者;七是喜欢侵略的统治者。就这几个魔王,能起到神对世界的干涉的作用吗?
八之魔王和勇者的定位重复,会出现的原因是知道,但结合剧情,只能说是一个「强行设定」。
看到这里,可能已经有聪明的读者猜到,作为魔人族的女主角必然和勇者或魔王有所关联,所以才会被驱逐,所以男主角才会为了女主角讨伐魔王。
是的,女主角是八之魔王,男主角是勇者,而这些设定,恰好是在第三卷后大量出现并逐渐补完的。
简单归纳一下剧情:
二之魔王因个人兴趣干掉了一之魔王,并把之后诞生的一之魔王候选人也干掉。
随后女主角诞生,女主角是双胞胎之一,她的姐姐是新的一之魔王候选人,而女主角是八之魔王候选人 (族人似乎不知道此事,翻译的质量太差,没读懂这里) 。
她们族人认为二之魔王知道后会干掉她们姐妹,因此编造理由,把女主角定为罪人驱逐出境,以保护姐妹两人,也让姐姐有时间成长为魔王对抗二之魔王。
女主角被男主角所救,并爱上了男主角 (是的,从很早就开始,女主角并不认为男主角是父亲的角色) 。
女主角在得知男主角将会比自己更早老去之后,在和男主角成为情侣之时,开始谋求魔王之力,将男主角收编为眷属,以求能在一起直到死亡。
因为女主角成为八之魔王,七大魔王联合开会 (没错,开会!) 决议将八之魔王抹杀,而女主角姐姐此时以成为一之魔王,亦知道八之魔王是其妹,因此说服其他魔王将抹杀八之魔王更改为封印八之魔王。
女主角在男主角面前消失后,男主角分析认为只有魔王才能做到此事 (伤害魔王) ,且因为自己并没有消失 (死亡) ,判断女主角仍存活,因此开始讨伐魔王。
因为男主角拥有勇者的能力,女主角在创造眷属时把自己的力量大部分都给了男主角,因此男主角很容易就讨伐了六位魔王。
女主角因为男主角的勇者加护,封印效果减弱,在多位魔王被讨伐后,女主角从封印中逃离,并到达了一之魔王的据点。
男主角在讨伐一之魔王时,和女主角重逢,之后停止讨伐身为女主角姐姐的一之魔王。
大团圆结��。
WTF?!
看前两卷知道男主角是很强的冒险者,突然冒出勇者属性是闹哪样?
女主角突然变成魔王又是闹哪样?
最不可思议的是,女主角知道八之魔王的能力,也知道自己姐姐是一之魔王,为了和男主角天荒地老就接受了魔王身份。
在接受魔王身份后,发现六大魔王要对其不利是,决然地抛下男主角赴死。
既然知道会死,为什么不和男主角以有限生命的形式活下去呢?
以前面对女主角性格的描写,女主角应该能想到自己一旦死去,男主角会推理出谁下的手并且复仇和魔王失去制约后可能的行动,因自己而造成大量无辜的人收到牵连,不是之前塑造的女主角的性格啊。
女主角姐妹,女主角活着,意味着她姐姐将失去不死身,会慢慢死去,这个设定也很诡异,而且最后也没交代如何解决的
原来「魔王」不是「魔王」,只是「魔人族之王」啊……
勇者和魔王之力居然不会冲突,导致男主角变无敌,七大魔王中单挑最强战力的二之魔王和男主角的一战变成了男主角单方面殴打小朋友的局面……
相当多的伏笔没用。
和其他人族共生的三之魔王看上去挺好的一个领导者老头,硬是被男主角砍了。
提供八之魔王的情报的五之魔王没有战斗力就算了,站在勇者面前,知道他要为八之魔王复仇,居然没说出封印一事,枉费了看了一整座塔书的魔王身份。
有着战士的矜持的六之魔王,在和男主角来了一场荣誉的决斗后就挂了。
自愿卖身给二之魔王以保女儿安全的女主角母亲,最后只起到透露二之魔王位置并为男主角创造了和二之魔王单挑的机会之后就死去,退出舞台。
男主角强大的背景也没有利用上,比如能制作强大魔道具且和幻兽共存的老家。
女主角对魔法的特殊天赋。
先吐这么多吧……总之,后三卷没有前两卷那么有意思,总有一股想办法凑出一个结局的味道……
0 notes
chrisyip · 9 years ago
Text
cd automatically after git clone
git clone <repository> && cd $(basename $_ .git)
basename is a standard UNIX computer program. When basename is given a pathname, it will delete any prefix up to the last slash ('/') character and return the result.
https://en.wikipedia.org/wiki/Basename
$_: The underscore variable is set at shell startup and contains the absolute file name of the shell or script being executed as passed in the argument list
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_02.html#table_03_03
0 notes
chrisyip · 9 years ago
Photo
Tumblr media
51K notes · View notes
chrisyip · 9 years ago
Text
git subtree
Git subtree is a useful way to adding private module to your project.
Pros:
No extra ssh configuration or private services (e.g. private npm modules) needed.
Modules are merged into parent repo, other collaborators can easily pull your commit without any trouble.
If someone wants to contributing back to private module, you just need to add them to the repo of private module.
# Add a git repo as a module git remote add -f REMOTE_NAME [email protected]/module.git git subtree add --prefix path/to/module REMOTE_NAME --squash # Updating module git fetch REMOTE_NAME master git subtree pull --prefix path/to/module REMOTE_NAME master --squash # Contributing back to module git subtree push --prefix=path/to/module REMOTE_NAME master
Git subtree: the alternative to Git submodules
0 notes
chrisyip · 9 years ago
Quote
What most people do when looking for, say, an iPhone notes app, is search the App Store for “notes”, and then start downloading free apps until they find one that seems good enough. There are so many free apps in a category like notes that paid ones — even if they’re just $1 — never get a look.
Sad, but true.
Via: http://daringfireball.net/2016/08/vesper_adieu
0 notes
chrisyip · 9 years ago
Text
JavaScript: detect if element is in view
/** * Detect if element is in view * * @method isElementInView * @param {HTMLElement} element the target element * @param {HTMLElement} [parentElement] container element, default is widnow * @param {Boolean} [ignoreBottom] useful when element is taller than container * @return {Boolean} element is in view or not */ function isElementInView (element, parentElement, ignoreBottom) { if (element instanceof HTMLElement === false) { return false } const rect = element.getBoundingClientRect() if (parentElement instanceof HTMLElement) { const parentRect = parentElement.getBoundingClientRect() const topInView = rect.top >= parentRect.top && rect.top < parentRect.bottom && rect.left >= parentRect.left && rect.left < parentRect.right if (ignoreBottom) { return topInView } return topInView && rect.bottom <= parentRect.bottom && rect.right <= parentRect.right } const topInView = rect.top >= 0 && rect.left >= 0 && rect.top < window.innerHeight && rect.left < window.innerWidth if (ignoreBottom) { return topInView } return topInView && rect.bottom <= window.innerHeight && rect.right <= window.innerWidth }
0 notes
chrisyip · 9 years ago
Text
JavaScript: Save File (Blob) to Disk
JavaScript 保存 Blob 到硬盘很简单:
const URL = window.URL || window.webkitURL const a = document.createElement('a') // 触发系统的文件保存对话框 a.download = 'filename' // 将 Blob 转换为 blob:http... const url = URL.createObjectURL(BLOB) // 模拟 <a> 点击事件 a.href = url a.click() // 销毁 blob:http... URL.revokeObjectURL(url)
对于在线资源,可以这样:
const req = new XMLHttpRequest() req.open('GET', '/path/to/file', true) req.responseType = 'arraybuffer' req.onload = function () { const arrayBuffer = req.response if (arrayBuffer) { const blob = new Blob([blob], { type: 'MIME_TYPE' }) // download(blob) } } // 处理下载进度 req.addEventListener("progress", PRGRESS_UPDATE_HANDLER) // or req.onprogress = PRGRESS_UPDATE_HANDLER req.send()
在编写 Electron 客户端时,这就方便很多了,做一个下载管理器也没问题。
参考资料:
Sending and Receiving Binary Data
URL
0 notes
chrisyip · 9 years ago
Text
Philips TX2BT 蓝牙耳塞简评
最近入了一副 Philips TX2BT 蓝牙耳塞,淘宝各种优惠后 640 多人民币到手,大概长这样:
Tumblr media
图片来源:http://watchmono.com/blog-entry-5782.html
由于蓝牙的各种限制,其实在便携耳塞方面并没有太出彩的产品,一直以来都没有找到好的蓝牙耳塞,「蓝牙听个响」并不完全错。而耳机方面就不一样了,比如我一年前入手的 Jabra Revo Wireless 就让我很满意。
由于有 Jabra 在先,我对 TX2BT 的期望其实挺高的,但结果只是差强人意。
���点:
不错的连接性能,连接速度、稳定性让人满意
体积便携、重量轻
可以同时连接两台设备,切换也算不错
音质是一般 4-500 价格段的耳塞的水准 (仅指官方价格)
耳塞佩戴体验不错,使用默认塞的情况下连续听 2-3 小时,耳朵仅有少许不适
缺点:
续航方面不合格,时间可接受,但充电体验不合格
外观设计不算合理,接听电话等体验不合格
偶有突然自动关机的情况
总结:在 600 以下的价位或确实需要蓝牙,TX2BT 值得考虑,但如果你依赖蓝牙耳塞作为电话、语音工具,不建议购买。
音质:不会让你有惊喜,也不会让你接受不能。
连接性能:带出街,手机口袋,基本上不会有太多连接不正常的感受,声音卡顿的概率很低。
续航问题:能连续播放 4 小时,以耳塞来说中规中矩,但充电方面则让人无法接受。在某次连续播放 4 小时候,听到电量低的提示音之后,就直接接 USB 充电。3-40 分钟后,拿起 TX2BT 发现已自动关机,开机之后响了一声电量低就自动关机,看样子似乎是无法在开机时充电,而且没有快速充电功能,对于早上带去公司,午休充两小时再坚持到下班的常见使用场景来说,实在麻烦——你需要记住先关机才能充电,否则会浪费几十分钟的充电时间,可能就无法支撑下午的使用时间。
外观设计问题:Philips 把电池和蓝牙零件放置在了中间位置 (见上图中间印着 Philips 字眼的零件) ,在佩戴的时候,由于它属于比较重的零件,会往下坠,会把线往后拉。由于整体重量比较轻,在头部不左右转动时,并不会感觉到有异样,但一旦左右转动头部,就感觉得到拉扯感,可能就需要再去调整位置;由于 TX2BT 的线材并不是硬式设计 (1,2) ,所以在线被往后拉扯的情况下,麦克风的位置就会跑到不合适接收语音的位置,这导致你在打电话时需要用手把麦克风往嘴边送,不然要么吼,要么听着别人不停地抱怨你声音好小或听不清。所以 TX2BT 并不适合对通话有中度以上需求的人。
在最后,再安利一下 Jabra Revo Wireless,海淘一千人民币出头,但续航能力、音质和通话性能都让人满意,只是连续使用 2-3 小时耳朵会比较疼,另外不知道是不是 iPhone 的问题,我戴它出门会有明显的连接障碍。
0 notes
chrisyip · 9 years ago
Text
mpv - the best video player
macOS 用户其实挺苦的,好用的视频播放软件没有几个,MPlayerX、Movist、VLC 各有各的问题,不像 Windows 那样有众多选择,并且质量都不差。由于 MPlayerX 和 Splayer 的问题让我无法忍受,所以选择了 VLC,毕竟开源,可以保证:
更新相对活跃
对大多数问题基本会有解决方案 (比如 GBK 的字幕)
不存在陷阱
不会突然终止维护 / 开发
然而在最近用 VLC 播放某些视频时遇到花屏、灰屏甚至突然没声音的情况,让我萌生了找更好的代替品的想法。在试用了大部分知名的播放软件,对 Mac App Store 免费榜排名第一的 Elmedia Player 对字幕支持很差、DivX 安装包居然要管理员权限感觉绝望,正准备购入 Movist 的时候,发现了 mpv,一款基于 MPlayer 的开源项目。
试用了一下,确实不错:
轻,启动快
播放性能优秀
无框模式
同样是开源项目,靠社区的力量还是有保障的
其中无框模式相当赞,比 VLC 方便:
Tumblr media
mpv 界面比较简单,不具备配置等菜单;鼠标功能也比较简单,右键是播放或暂停。不过一般配置好之后,只要有方向键 (左右是前进或后退 10 秒,上下则为 60 秒) 和空格 (播放或暂停) 就够了。
由于没有配置菜单,所以需要通过配置文件来做自定义,所幸的是,配置一点都不复杂,也不多。以 macOS 为例。
首先安装就通过 Homebrew 来完成,虽然可以下载已编译好的执行文件,但还是 Homebrew 方便些:
brew install mpv --with-bundle brew linkapps mpv brew install enca
然后建立一个配置文件 ~/.config/mpv/mpv.conf,以下是能获取不错体验的最简配置:
# video playback vo=opengl-hq:icc-profile-auto autofit-larger=95%x90% autofit-smaller=30%x30% # tries to automatically enable hardware decoding hwdec=auto # osd message, you can press o to display the osd message osd-bar-align-y=0.9 osd-bar-h=1.2 osd-border-size=1 osd-duration=2000 osd-font='PingFangSC-Regular' # player window ontop=yes no-border # subtitle sub-auto=fuzzy sub-text-font='PingFangSC-Regular' # language alang=en,eng,zh,cmn,chi,zho slang=cmn,chi,zho,zh,eng,en # convert non-utf8 chinese subtitle file to utf8 # brew install enca subcp=enca:zh:cp936 # program behaviors save-position-on-quit ytdl
重新启动 mpv 就能应用配置,另外 mpv 还能直接播放 B 站、Youtube 等网站的视频,虽然需要其它工具的支持,这里就不详述,参考这个项目吧:https://github.com/m13253/BiliDan。
如果你对 mpv 感兴趣,可以到 https://mpv.io/ 去看看。至于文中提到的几个播放软件,我连官网链接都懒得放的,自然是不推荐的。
0 notes
chrisyip · 9 years ago
Link
A technical leader's role is to prevent the most egregious mistakes and otherwise let people do what they feel is right.
0 notes
chrisyip · 9 years ago
Text
nginx: ERR_CONTENT_LENGTH_MISMATCH
因为项目有在 node 使用 SSL 的需要,考虑到线上环境也是通过 nginx 来处理 SSL 请求,所以我在本地也采用了 nginx 来处理。但是在请求动态生成的静态文件时,经常会出现 ERR_CONTENT_LENGTH_MISMATCH 错误,���了一圈之后发现是 nginx 由于请求压力,想从缓存目录获取结果时,没有权限访问该目录导致的。
解决方案如下:
确定 nginx 启动的用户和用户组
修改缓存目录的所有者 chown -R USER:GROUP NGINX_PROXY_TEMP
Mac 且通过 Homebrew 安装的,缓存目录应该是 /usr/local/var/run/nginx/proxy_temp。
0 notes
chrisyip · 10 years ago
Text
OS X:修复 Finder 不显示预览图和 Quick Look 无法预览文件的问题
最近遇到了 Finder 无法显示和预览图片、视频等多媒体文件的问题,按照往常的经验,在命令行执行了以下命令:
qlmanage -r qlmanage -r cache
但问题并没有解决,我的情况更严重。经过一番 Google,我进行了如下操作:
删除所有 Quick Look 插件。
进入 ~/Library/Preferences 删除以下几个文件:
com.apple.quicklookconfig.plist com.apple.QuickLookDaemon.plist com.apple.quicklook.satellite.plist com.apple.quicklook.ui.helper.plist (如果存在)
但我的问题依然无法解决,最后突然发现 qlmange 发现有一个参数 -p:
-p Compute previews of the documents
我抱着尝试的心态用 qlmange -p 预览了一张图片,看到如下错误信息:
qlmanage -p photo.png Testing Quick Look preview with files: photo.png 2016-03-01 17:59:50.481 qlmanage[10163:651452] [qlinfinite] Instantiated plugin in host with identifier (null) 2016-03-01 17:59:50.481 qlmanage[10163:651452] [qlinfinite] Found 35 system generators 2016-03-01 17:59:50.483 qlmanage[10163:651452] [qlinfinite] Registered generator CFBundle/CFPlugIn 0x7f9bd3e11f60 </usr/local/Cellar/macvim/7.4-97/MacVim.app/Contents/Library/QuickLook/QLStephen.qlgenerator> (bundle, loaded) for type public.png 2016-03-01 17:59:50.654 qlmanage[10163:651394] *** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0x9f03, name = 'com.apple.coredrag' See /usr/include/servers/bootstrap_defs.h for the error codes. 2016-03-01 17:59:50.951 qlmanage[10163:651394] *** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0xc23f, name = 'com.apple.tsm.portname' See /usr/include/servers/bootstrap_defs.h for the error codes. 2016-03-01 17:59:50.952 qlmanage[10163:651394] *** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0xc423, name = 'com.apple.CFPasteboardClient' See /usr/include/servers/bootstrap_defs.h for the error codes. 2016-03-01 17:59:50.952 qlmanage[10163:651394] void __CFPasteboardSetup() : Failed to allocate communication port for com.apple.CFPasteboardClient; this is likely due to sandbox restrictions
重点在这一句:
Registered generator CFBundle/CFPlugIn 0x7f9bd3e11f60 </usr/local/Cellar/macvim/7.4-97/MacVim.app/Contents/Library/QuickLook/QLStephen.qlgenerator> (bundle, loaded) for type public.png
这意思是 PNG 的 Quick Look 插件被换成了 MacVim 的 QuicklookStephen 插件,而这一个插件��用来预览文本文件,当然不可能预览图片等文件。
解决方案相当简单,删除 MacVim 再跑一次 qlmanage -r 等几个命令即可。
0 notes
chrisyip · 10 years ago
Text
Angular 1.x: 记录 $resource:badcfg 错误
相信在做 Angular 1.x 开发的时候,各位都有碰到过 $resource:badcfg 错误,这个错误很简单:就是本应该返回 Object 或者 Array 的 HTTP 请求结果返回了类型不匹配的结果:
This error occurs when the $resource service expects a response that can be deserialized as an array but receives an object, or vice versa. By default, all resource actions expect objects, except query which expects arrays.
虽然这个问题的描述已经很清晰,但是因为 Angular 并不会把相应请求的完整信息告诉你,所以 (特别是在生产环境) 你很难得知出问题的请求包含哪些请求参数、headers,以及服务器返回了什么样的数据。
在瀑布IM ,我们是通过这种方法来解决这个问题。
首先,得在 $resource 的 headers 里加一些东西:
$resource(url, paramDefaults, { ... query: { method: 'GET', isArray: true, { headers: { isArray: true } } } ... })
然后在 interceptors 里增加如下处理:
angular.module(’myApp’, []).config(['$httpProvider', function ($httpProvider) { $httpProvider.interceptors.push(function () { return { request: function (config) { if (config.headers.isArray) { config.isArray = true delete config.headers.isArray } return config }, response: function (response) { var config = response.config if (typeof config.isArray === 'boolean') { var data = response.data /** * 以下两种情况会触发记录到 Sentry 的行为 * - 如果 method 要求返回 Array 而数据不是 Array * - 如果 method 要求返回 Object 而数据不是 Object */ if (Array.isArray(data) !== config.isArray) { Raven.captureException(new Error('[badcfg] ' + config.url), { tags: { type: 'web' }, extra: { data: data, url: config.url, params: config.params } }) } } return response } } }) }])
因为我们用 Sentry 来收集错误,所以例子里是把数据发送到 Sentry。
0 notes
chrisyip · 10 years ago
Link
diff-so-fancy 是一个 Git Diff 强化工具,使用后效果如图:
Tumblr media
使用方法很简单:git diff --color | diff-so-fancy
0 notes