Blog

最近赋闲在家,没事发现用iphone捷径来拼长图很有意思,有时候连续的几张照片拼成一张长图,看起来很不错哦。 发朋友圈就可以在有限的9张图里面发出更多的图片。

在mac上,我也试了下拼长图,不过都没有那么方便。网上说的使用预览来拼图,我是真没学会。不过使用 imagemagick 带的命令行到是基本可以完成拼接。

可以使用下面的命行拼出一个横图。

convert -append in-1.jpg in-2.jpg out.jpg
可以使用下面的命行拼出一个竖图(也就是长图):
convert +append in-1.jpg in-2.jpg out.jpg

不过,可惜的是,如果一张是相机横着拍的,一张是竖着拍的,这样拼的长图中,会自动把图片旆转一下。感觉很不爽。 这个问题,手机中的拼长图捷径处理得比较好,不过这个捷径在图片多了以后,经常就会闪退。我看了一下该捷径的处理,发现它应该就是用的预览来合并的长图。 不过在处理时,它自动调整了图片的宽度。这个后面可以参考一下。

昨天试了下 Rsshub 。感觉还不错。

直接使用docker来安装的: docker pull diygod/rsshub 。然后直接拉起,把1200端口映射出来就安装好了:

docker run -d --name rsshub --env NODE_ENV=production -p 1200:1200 diygod/rsshub

官网 有提供很多的路由。我先用来订阅微信公众号。使用的是这个:

公众号(瓦斯来源)

作者: @DIYgod

举例: https://rsshub.app/wechat/wasi/5b575db858e5c4583338db11

路由: /wechat/wasi/:id

参数:

    id, 必选 -

    瓦斯公众号 id, 可在瓦斯搜索公众号, 打开公众号页, 在 URL 中找到 id

比如我的机器的域名是 xxxx.com,则我可以订阅 http://xxx.com:1200/wechat/wasi/5b575db858e5c4583338db11 这个rss源。 不同的id就是不同的公众号,对应的id可以去 瓦斯 里面搜公众号名字,找到后点进去,url后面的id就是这里使用的id。

这样的rss不是全文的,看文档,可以使用efb来借telegram中转一下获得全文,但是,这需要一个空闲的微信来登陆efb。我没有,所以我没法使用这个办法。

不过,我发现instapaper可以帮我干这个事情。 现在我一般是,用在inoreader中订阅这些公众号,手机上用reeder看。 觉得需要读的,就在reeder中发送到instapaper中。 由instapaper负责帮我把全文拉下来。我instapaper主要是在电子书上看的。 最后,需要看的文章都在instapaper中,电子书定期联网就拉下来了。而且都是全文哦。

在安装了 Calibre 后,可以使用命令行整个网页转为电子书。 比如,我想把我自己的blog转为mobi,可以使用下面的命行:

ebook-convert index.html book.epub
如果需要转换网络中的某个网站的话,可以先用wget把它下载下来:
wget -r -p -np -k <url>

记录了一些协程的笔记: Coroutins-协程

使用callibre抓取instapaper保存的文章时,总是最新的文章在最前,这样看起来不太爽。因为我总是希望最先阅读最旧的文章。

然后我就找到了callibre的recipe中有这样一个功能:

reverse_article_order = True
直接就可以把抓取的文章顺序反转。使用方法就是直接使用高级修改callibre的recipe,加入下面一句就可以了(默认好像它是被注释掉了)。 所以我的recipe看起来可能就是这样的:

# Calibre recipe for Instapaper.com (Stable version)
#
# Homepage: http://khromov.wordpress.com/projects/instapaper-calibre-recipe/
# Source: https://github.com/kovidgoyal/calibre/blob/master/recipes/instapaper.recipe

from calibre.web.feeds.news import BasicNewsRecipe

class AdvancedUserRecipe1299694372(BasicNewsRecipe):
    title = u'Instapaper'
    __author__ = 'Darko Miletic, Stanislav Khromov, Jim Ramsay'
    publisher = 'Instapaper.com'
    category = 'info, custom, Instapaper'
    oldest_article = 365
    max_articles_per_feed = 100
    reverse_article_order = True
    no_stylesheets = False
    extra_css = 'q { font-style: italic; } .size3mode { color: black; }'
    remove_javascript = True
    remove_tags = [
        dict(name='div', attrs={'id': 'text_controls_toggle'}),
        dict(name='script'),
        dict(name='div', attrs={'id': 'text_controls'}),
        dict(name='section', attrs={'class': 'primary_bar'}),
        dict(name='div', attrs={'class': 'modal_group'}),
        dict(name='div', attrs={'id': 'editing_controls'}),
        dict(name='div', attrs={'class': 'modal_name'}),
        dict(name='div', attrs={'class': 'highlight_popover'}),
        dict(name='div', attrs={'class': 'bar bottom'}),
        dict(name='div', attrs={'class': 'evernote_confirm'}),
        dict(name='div', attrs={'id': 'controlbar_container'}),
        dict(name='div', attrs={'id': 'footer'}),
        dict(name='div', attrs={'id': 'speedRead'}),
        dict(name='label')
    ]
    use_embedded_content = False
    needs_subscription = True
    INDEX = u'https://www.instapaper.com'
    LOGIN = INDEX + u'/user/login'

    feeds = [
        (u'Instapaper Unread', u'https://www.instapaper.com/u')
        #            (u'Instapaper Starred', u'https://www.instapaper.com/starred')
    ]

    def get_browser(self):
        br = BasicNewsRecipe.get_browser(self)
        if self.username is not None:
            br.open(self.LOGIN)
            br.select_form(nr=0)
            br['username'] = self.username
            if self.password is not None:
                br['password'] = self.password
            br.submit()
        return br

    def parse_index(self):
        totalfeeds = []
        lfeeds = self.get_feeds()
        for feedobj in lfeeds:
            feedtitle, feedurl = feedobj
            self.report_progress(0, 'Fetching feed' + ' %s...' %
                                 (feedtitle if feedtitle else feedurl))
            articles = []
            soup = self.index_to_soup(feedurl)
            for item in soup.findAll('a', attrs={'class': 'article_title'}):
                articles.append({
                    'url': 'https://www.instapaper.com' + item['href'],
                    'title': item['title']
                })
            totalfeeds.append((feedtitle, articles))
        return totalfeeds

今天使用了一下 hammerspoon ,我主要想用来直接用按键切换应用程序。

下载后,具体做法就是直接新建 ~/Users/pengpengxp/.hammerspoon 目录,目录中新建 init.lua 文件。

然后我直接写了下面的内容:

hs.hotkey.bind({"cmd", "control"}, "E", function()
      hs.execute("open /Applications/Emacs.app/")
end)

hs.hotkey.bind({"cmd", "control"}, "P", function()
      hs.execute("open /Applications/Opera.app/")
end)

hs.hotkey.bind({"cmd", "control"}, "F", function()
      hs.execute("open /Users/pengpengxp")
end)

hs.hotkey.bind({"cmd", "control"}, "C", function()
      hs.execute("open /Applications/Calendar.app")
end)

hs.hotkey.bind({"cmd", "control"}, "I", function()
      hs.execute("open /Applications/iTerm.app")
end)

hs.hotkey.bind({"cmd", "control"}, "G", function()
      hs.execute("open /Applications/Google\\ Chrome.app")
end)

hs.hotkey.bind({"cmd", "control"}, "O", function()
      hs.execute("open //Applications/WeChat.app")
end)

-- reload
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "R", function()
  hs.reload()
end)
hs.alert.show("Config loaded")

基本就可以使用了。不过我原本习惯是,按住两边的command然后加按键来切换的。我没有找到hammerspoon识别rightcommand和leftcommand的功能。 我看起来好像它只识别command,而不能区分是哪边。

之前一直没搞太明白云上IaaS、PaaS和SaaS的区别。这次翻译一篇文章。 原文是 saas-vs-paas-vs-iaas-whats-the-difference,我的翻译 IaaS、PaaS和SaaS的区别

然后又看下了知乎的回答,我觉得讲得不错:链接是 这里

  • IaaS就像之前我搭建的Openstack平台一样,提供给用户的就是直接的计算节点等等。
  • PaaS应该来说是面象软件开发人员的服务,云提供硬件、OS、编程语言、开发库、布署工具,帮助开发者更快地进行开发,如Google的GAE。
  • SaaS是面象软件消费者的,用户无需安装,直接通过济览器就可以使用云提供的服务,比如Gmail。