东东东 陈煜东的博客

Disqus已被认证

社交化评论系统Disqus在国外非常的流行,前几个月,我也是从duoshuo转到了Disqus,感觉评论的风格还算简洁,个人感觉也挺喜欢的。

用了一段时间,Disqus用HTTP无法访问了。为此专门研究了一下,原来HTTPS还可以访问,特意加将全站转向了HTTPS。没想到用了几个月,这两天发现评论框出不来了。

找了站长工具超级PING,发现基本一片红色呀。

大陆的访问disqus情况

大陆的访问disqus情况

各个地域的域名DNS解析

各个地域的disqus域名解析

各个地域的disqus域名解析

域名解析出来,已经到了『阿塞拜疆』,一个中东国家。

要想继续使用Disqus,那么只能靠有个海外的服务器进行反向代理了。目前没有购买海外服务器,改天看看有没有能搞一个海外服务器做反向代理。

本来想再用回duoshuo的,但是微博的头像竟然没有HTTPS的连接,想想还是先算了吧。真好搞,网上有很多『多说完美HTTPS』教程,看着搞代理,修改源码,都不太稳定。

分类: 网站建设

Graphviz安装失败的一个尝试

Graphviz来对sphinx进行画图,不过发现一直无法编译出来。

PS:Graphviz的官网在大陆访问非常的慢。

首先参考http://graphviz.org/Download_linux_rhel.php,增加一个repo源,

然后执行yum install 'graphviz*'安装graphviz的软件。

在安装的过程中出现了

Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Hashtbl) = 718cd6ce8bc18371ce22483e362f78b4
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Hashtbl) = 024edc3512403b725052aec8e41ed971
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Array) = 4d5efba91ec70acd7b184fd4b277708c
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Array) = 8a6bb22925744456eb66180ea42e3344
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(List) = bd7c662c09e850306a62c12fed5ef5ce
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(List) = d757117653d9319fefb7ddc78a998f41
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(runtime) = 4.00.1
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(runtime) = 4.01.1
ocaml(runtime) = 4.01.0
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Gc) = 23b8d067f883f7a218c4945a42625a31
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Gc) = 292a1cd61d8e068943589882415bdf7d
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Obj) = ad977b422bbde52cd6cd3b9d04d71db1
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Obj) = b0adfa4175f86e4394859886c1a374bb
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Int32) = 265928798c0b8a63fa48cf9ac202f0ce
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Int32) = ad06f04cfca6d404d1de76c3dc67324a
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Callback) = 6fd6d47b2f6a171a493621bc5edbfb32
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Callback) = 198fb4bcde892143b0866b03cfae8085
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(List) = bd7c662c09e850306a62c12fed5ef5ce
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(List) = d757117653d9319fefb7ddc78a998f41
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Callback) = 6fd6d47b2f6a171a493621bc5edbfb32
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Callback) = 198fb4bcde892143b0866b03cfae8085
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Pervasives) = 4836c254f0eacad92fbf67abc525fdda
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Pervasives) = 36b5bc8227dc9914c6d9fd9bdcfadb45
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Hashtbl) = 718cd6ce8bc18371ce22483e362f78b4
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Hashtbl) = 024edc3512403b725052aec8e41ed971
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Pervasives) = 4836c254f0eacad92fbf67abc525fdda
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Pervasives) = 36b5bc8227dc9914c6d9fd9bdcfadb45
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Array) = 4d5efba91ec70acd7b184fd4b277708c
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Array) = 8a6bb22925744456eb66180ea42e3344
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(runtime) = 4.00.1
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(runtime) = 4.01.1
ocaml(runtime) = 4.01.0
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Int32) = 265928798c0b8a63fa48cf9ac202f0ce
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Int32) = ad06f04cfca6d404d1de76c3dc67324a
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Gc) = 23b8d067f883f7a218c4945a42625a31
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Gc) = 292a1cd61d8e068943589882415bdf7d
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Int64) = 0d5ecd8dffcffac43aec2ebe427d3bde
Available: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Int64) = 3945db6e8df0d5a79bcbc949ee550d52
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Obj) = ad977b422bbde52cd6cd3b9d04d71db1
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Obj) = b0adfa4175f86e4394859886c1a374bb
Error: Package: graphviz-lang-ocaml-2.38.0-1.el7.x86_64 (graphviz-stable)
Requires: ocaml(Int64) = 0d5ecd8dffcffac43aec2ebe427d3bde
Installing: ocaml-runtime-4.01.0-22.6.el7.x86_64 (base)
ocaml(Int64) = 3945db6e8df0d5a79bcbc949ee550d52
You could try using --skip-broken to work around the problem
You could try running: rpm -Va --nofiles --nodigest

看这个论坛说,修改之后,再次安装,果然可以装上。

Just edit the snapshot section so that “enabled=1″, and correspondingly disable the stable section.

[graphviz-snapshot]
name=Graphviz - RHEL $releasever - $basearch
baseurl=http://www.graphviz.org/pub/graphviz/development/redhat/el$releasever/$basearch/os/
enabled=1
gpgcheck=0
skip_if_unavailable=1

[graphviz-snapshot-source]
name=Graphviz - RHEL $releasever - Source
baseurl=http://www.graphviz.org/pub/graphviz/development/SRPMS/
enabled=1
gpgcheck=0
skip_if_unavailable=1

最后安装的dot程序

dot - graphviz version 2.39.20160710.1729 (20160710.1729)
libdir = "/usr/lib64/graphviz"
Activated plugin library: libgvplugin_dot_layout.so.6
Using layout: dot:dot_layout
Activated plugin library: libgvplugin_core.so.6
Using render: dot:core
Using device: dot:dot:core
The plugin configuration file:
        /usr/lib64/graphviz/config6
                was successfully loaded.
    render      :  cairo dot dot_json fig gd json json0 map mp pic pov ps svg tk vml vrml xdot xdot_json
    layout      :  circo dot fdp neato nop nop1 nop2 osage patchwork sfdp twopi
    textlayout  :  textlayout
    device      :  bmp canon cmap cmapx cmapx_np dot dot_json eps fig gd gd2 gif gtk gv ico imap imap_np ismap jpe jpeg jpg json json0 mp pdf pic plain plain-ext png pov ps ps2 svg svgz tif tiff tk vml vmlz vrml wbmp x11 xdot xdot1.2 xdot1.4 xdot_json xlib
    loadimage   :  (lib) bmp eps gd gd2 gif ico jpe jpeg jpg pdf png ps svg xbm

PS:如果有些程序没有安装好,那么没办法生成pdf的格式。

如下面的错误信息,硬是没有pdf的格式。原来是插件没有安装全。

Graphviz produced errors. Verify it has support for filetype=pdf, or use filetype=dot.
Original error: Format: "pdf" not recognized. Use one of: canon cmap cmapx cmapx_np dot eps fig gd gd2 gif gv imap imap_np ismap jpe jpeg jpg plain plain-ext png ps ps2 svg svgz tk vml vmlz vrml wbmp xdot

不过还残留一个没有解决的问题

[stderr]
Warning: flat edge between adjacent nodes one of which has a record shape - replace records with HTML-like labels
  Edge A -> B
Error: lost A B edge

我把两个node放在同一个level,然后做了箭头,报错了,得再研究研究。

分类: python, 软件

Python重新抛出异常的姿势

异常对于一个语言来说非常重要,异常的栈信息对于开发者特别重要,因为可以根据异常栈来找到第一次抛出异常的地方。但是懂得正确的抛出异常的人不是很多。

首先,以下是最糟糕的

def revert_stuff():
    pass

def some_code():
    raise Exception('oops, some error occur')

try:
    some_code()
except:
    revert_stuff()
    raise Exception("some_code failed!")
Traceback (most recent call last):
  File "1.py", line 11, in <module>
    raise Exception("some_code failed!")
Exception: some_code failed!

为什么说是最糟糕呢?因为关于some_code()的失败信息全部都丢失了。不过这些异常堆栈,可能是我们期望的信息,也可能不是。

以下代码是稍微改进过,但还是不是非常好:

def revert_stuff():
    pass

def some_code():
    raise Exception('oops, some error occur')

try:
    some_code()
except:
    import traceback
    traceback.print_exc()
    revert_stuff()
    raise Exception("some_code failed!")
Traceback (most recent call last):
  File "2.py", line 8, in <module>
    some_code()
  File "2.py", line 5, in some_code
    raise Exception('oops, some error occur')
Exception: oops, some error occur
Traceback (most recent call last):
  File "2.py", line 13, in <module>
    raise Exception("some_code failed!")
Exception: some_code failed!

使用traceback.print_exc() 把原始的异常堆栈(traceback)打印了出来。从某些角度来看这是最好的方法了,因为可以异常的错误信息找出来。但是如果不想恢复着新异常信息,那么应该这么做:

def revert_stuff():
    pass

def some_code():
    raise Exception('oops, some error occur')

try:
    some_code()
except:
    revert_stuff()
    raise
Traceback (most recent call last):
  File "3.py", line 8, in <module>
    some_code()
  File "3.py", line 5, in some_code
    raise Exception('oops, some error occur')
Exception: oops, some error occur

使用不用带任何参数raise可以重新抛出最后的异常。有时人们直接留空从来不用except:语句,但是这个特殊的形式(except: + raise)也是可以的。

有另外一种raise抛出异常的方式,知道的人比较少,但是也很容易上手。类似无参数的raise一样,这种方法也可以保留异常堆栈:

def some_code():
    raise Exception('oops, some error occur')

def maybe_raise(exc_info):
    raise exc_info[0], exc_info[1], exc_info[2]

try:
    some_code()
except:
    import sys
    exc_info = sys.exc_info()
    maybe_raise(exc_info)
Traceback (most recent call last):
  File "4.py", line 12, in <module>
    maybe_raise(exc_info)
  File "4.py", line 8, in <module>
    some_code()
  File "4.py", line 2, in some_code
    raise Exception('oops, some error occur')
Exception: oops, some error occur

如果你需要在异常发生的代码的其他地方处理异常是个不错的选择。但通常它不是很方便,因为这样比较晦涩难懂。

还有一类经常修改异常堆栈的情况是:想加一些额外的信息到异常堆栈中。

for lineno, line in enumerate(file):
    try:
        process_line(line)
    except Exception, exc:
        raise Exception("Error in line %s: %s" % (lineno, exc))

这里保留了异常信息,但却丢失了异常堆栈。有一个方法可以保留异常堆栈。下面的方法不仅可以保留异常,也可以改变异常的信息。

except Exception, exc:
    args = exc.args
    if not args:
        arg0 = ''
    else:
        arg0 = args[0]
    arg0 += ' at line %s' % lineno
    exc.args = arg0 + args[1:]
    raise

有些小尴尬。从技术上讲(虽然它不建议使用),你可以抛出任何的异常。如果使用except Exception:那么就不能捕获一些例如string异常或者其他异常。想要这么用取决于是否关心这些场景。不过异常也可能没有.args属性,或者异常的字符串信息不能从这些参数中获取,又或者有其他的方法展示(例如KeyError信息有些不同 ) 。因此这不是万能的。想要增强版,可以这么做:

except:
    exc_class, exc, tb = sys.exc_info()

exc_class是一个字符串类型,不过可能有人会raise "not found"。所以这种风格被废弃了。如果坚持想去把周围的东西搞的一团糟,可以这么用:

new_exc = Exception("Error in line %s: %s"
                    % (lineno, exc or exc_class))
raise new_exc.__class__, new_exc, tb

这样改变了异常类周围使得它变的混乱了,但至少保留完好异常堆栈。在异常堆栈中raise ValueError(...)或者在错误信息raise Exception可能看上去有些奇怪。

小结:Python2中的较佳方法

以下是在Python2中一个较佳重新抛出异常的方法。

try:
    code()
except:
    exc_info = sys.exc_info()
    try:
        revert_stuff()
    except:
        # If this happens, it clobbers exc_info, which is why we had
        # to save it above
        import traceback
        print >> sys.stderr, "Error in revert_stuff():"
        traceback.print_exc()
        raise exc_info[0], exc_info[1], exc_info[2]

在with语句中抛出异常

如果想在某些场景下保留异常,有些场景下又想不捕获异常,那么可以怎么做

class ignore_or_reraise_exception(object):
    def __init__(self, reraise=True):
        self.reraise = reraise

    def __enter__(self):
        self.type_, self.value, self.tb, = sys.exc_info()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type is not None:
            if self.reraise:
                log.error('Original exception being dropped: %s' % self.value)
        if self.reraise:
            return True   #  reraise exception
        return False    # ignore exception

....
except Exception:
   with ignore_or_reraise_exception(reraise=False) as ctxt:
       if statements to determine whether to raise a new exception:
           # Not raising a new exception, so reraise
           ctxt.reraise = True

通过这个方法,可以自由的选择是忽略异常,还是想继续抛出异常。当需要抛出异常的时候,指定属性ctxt.reraise = True即可。

另外可以在ignore_or_reraise_exception中的处理异常,可以把异常都收集起来到一个全局变量,最后程序退出的时候,把所有的异常都打印出来。

总结:兼容Python2、Python3的重新抛出异常方法

在Python2中,重新抛出异常是用raise exc_info[0], exc_info[1], exc_info[2]这样的三个参数。但在Python3中却不一样了。

这个时候只能使用兼容Python2、Python3的类库six了。

使用方法

def some_code():
    raise Exception('oops, some error occur')

class SwaggerValidationError(Exception):
    pass

try:
    some_code()
except Exception as e:
    import six, sys
    six.reraise(
                SwaggerValidationError,
                SwaggerValidationError(str(e)),
                sys.exc_info()[2])

Traceback (most recent call last):
  File "5.py", line 14, in <module>
    sys.exc_info()[2])
  File "5.py", line 8, in <module>
    some_code()
  File "5.py", line 2, in some_code
    raise Exception('oops, some error occur')
__main__.SwaggerValidationError: oops, some error occur

参考文章:http://www.ianbicking.org/blog/2007/09/re-raising-exceptions.html

分类: python

sphinx doc正式支持中文搜索啦

之前Sphinx doc一直不支持web的中文搜索,一个牛逼的项目怎么能不支持中文搜索呢。看到现在这个项目的一个负责人是日本人,目前支持CJK的的搜索就是日本了,我觉得不应该呀,我大中华人杰辈出。果然在github上的pull request看到了台湾的enhao兄提交了繁体中文的搜索,看了代码的实现,里面是支持中文搜索的,于是在他的基础上修改了一些完善了简体中文的支持。

我一直觉得sphinx-doc这个项目很不错,可以写文档,写书,多多关注关注一下issue的列表。

上线发布

现在sphinx-doc的master或者v1.4版本后就支持中文(简体+繁体)搜索了。

sphinx-doc的中文搜索是依靠jieba这个开源的类库来实现的,这个类库就支持简体和繁体的切分,所以就很容易实现了。

使用

第一,你的系统需要安装jieba类库, pip install jieba

第二,接下来修改sphinx的conf.py文件,为项目设置为中文的搜索配置。

# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'
html_search_language = 'zh'

第三,可选配置

# A dictionary with options for the search language support, empty by default.
# 'ja' uses this config value.
# 'zh' user can custom change `jieba` dictionary path.
# html_search_options = {'dict': '/usr/lib/jieba.txt'}   # 根据需要设置jieba的词典路径

第四,接下来重新编译生成文档。make html

sphinx的基本搜索原理

在编译的时候:

  1. 先对文本进行切词,把中文切分,
  2. 然后制作一个大的map对象,把关键字做为key,url做为value,保存到js文件。
  3. 搜索的时候寻找对应的关键字key,拿到url作为列表展示。

后续计划

上线比较匆忙,还有一些中文搜索的计划

  • 支持python3的搜索
  • 添加测试的用例

分类: python

腾讯云招人啦~

2016开始啦,社招、校招、实习继续啦~ http://www.qcloud.com/

联系我

联系我~ Mjg2Mjg4NDE3QHFxLmNvbQ==

如果对虚拟化技术感兴趣,就联系我吧,这里有很多不同的岗位,不要局限于以下几个~,找我内推啦~

相关的岗位有:

  • 类openstack
  • kvm虚拟化
  • SDN虚拟网络
  • web开发
  • 运营开发
  • 运维

更多岗位参考-> 腾讯云招聘

腾讯云计算平台研发工程师

岗位职责

  • 负责腾讯云主机业务后台server研发;
  • 负责腾讯云主机虚拟化控制平台的相关架构和研发;
  • 参与相关产品需求讨论以及系统架构的设计和优化工作。

岗位要求

  • 本科及以上学历;
  • 2年以上python开发经验,有C/C++经验者优先;
  • 精通TCP/IP协议,进程间通讯编程,多线程编程等,熟悉Linux常见网络服务器模型;
  • 了解libvirt、qemu等虚拟化组件的原理和代码逻辑优先;
  • 了解KVM虚拟化,熟悉openstack的架构和主要流程,有相关领域工作经验的优先;
  • 具备良好的沟通表能力及团队协作精神、有较强的主动性、责任心与执行能力,具备良好的分析解决问题能力。

运营开发工程师

岗位职责

  • 负责云平台虚拟化运营支撑系统的研发工作,工作内容主要:
  • 腾讯云的资源全景视图,从物理层面到具体云主机的分层视图,包含资源的库存管理,消耗分析,扩容流程等;
  • 云主机调度核心算法的可视化,体现不同云主机的售卖对资源池的影响,从而为主打机型,营销活动,扩充资源提供依据;
  • 虚拟机管理相关运维流程实现,如虚拟主机资源池管理、母机初始化、子机投放工具等;
  • 负责腾讯云Api的相关开发工作。

岗位要求

  • 本科及以上学历;
  • 2年以上B/S架构系统分析设计经验;
  • 精通PHP开发技术,熟悉python,shell等脚本语言;
  • 熟练掌握常用Linux命令,熟练掌握la(n)mp架构,能够熟练对la(n)mp进行架设及配置;
  • 熟悉ITIL体系和运维流程,有相关自动化运维系统开发经验者优先;
  • 有数据库开发,数据分析经验者优先;
  • 熟悉虚拟化技术者(XEN、KVM)优先。

高级系统运维工程师

岗位职责:

  • 负责对虚拟化疑难问题分析解决,形成方法论,提升团队技术能力;
  • 负责通过技术手段、流程制度提升虚拟化平台可用性;
  • 负责分析业务不合理、不高效地方,提出优化改进方案并推进实施;
  • 负责腾讯云虚拟化运维平台规划,建设,不断提升运维效率。

岗位要求:

  • 本科及以上学历;
  • 3年以上相关工作经验,精通linux,windows操作系统,对系统性能相关问题有较深刻理解;
  • 熟悉主流虚拟化技术原理(如kvm,xen,hyper-v,lxc),有实际的对虚拟化疑难问题trouble shooting经验;
  • 熟悉TCP/IP协议,了解SDN相关技术,能够定位linux虚拟化环境下网络异常;
  • 擅长shell,python,perl中一种或几种,熟练应用awk、sed、grep、strace、tcpdump、gdb等常用命令;
  • 有过kernel研究及开发经验者优先。

分类: 生活

sphinx文档使用graphviz来画图

Sphinx是用来写文档的利器,虽然比Markdown来的麻烦一些,但是功能强大,用起来也还很不错。考虑到不同文档之间内的跳转,还有把文档从拆分成多个小文档,而且reStructuredText语言入门成本不高,所以用了sphinx-docs来做文档的编写。

Word来编写文档?呃。。。请赐我一刀。使用Word来进行编排文档,在多人协作的情况下,简直惨不忍睹,文档的格式乱七八糟。

reStructuredText再通过LeTax来编译生成pdf也是很方便的。

为什么要用graphviz来画图?

画图的软件并不是太多,一般的人会选择使用visio来进行画图,visio来画图确实可以,也无可厚非,所见即所得,容易上手。但是用于一个版本控制的文档,visio的版本控制就不是太好了。用文本来说就方便很多了。

有个ditaa使用ascii字符来画图的,http://ditaa.sourceforge.net/。很多工业界的IETF文档用它来画图

+--------+   +-------+    +-------+
|  cRED  | --+ ditaa +--> |       |
|  Text  |   +-------+    |diagram|
|Document|   |!magic!|    |  cGRE |
|     {d}|   | cYEL  |    |       |
+---+----+   +-------+    +-------+
    :                         ^
    |       Lots of work      |
    +-------------------------+

ditaa

但是和中文结合在一起排版就不是太好了。中文一个字符占两个英文字符的位置,导致原图不和谐。还有另外一个原因,感觉编译ditaa的速度有些慢。

下载安装Graphviz

Windows下载Graphviz,解压到一个路径下,然后把其bin目录加入到环境变量中。在cmd中dot -V来验证是否可以使用dot编译了。

Linux请使用系统自带的包管理程序来安装atp-get install graphviz,和Windows同样的验证方法。

Sphinx 配置文件修改

Sphinx项目也需要做一些变更,因为开启了Graphviz插件。修改conf.py

# 通过配置开启graphviz插件
extensions = ['sphinx.ext.graphviz']

# 设置 graphviz_dot 路径
graphviz_dot = 'dot'
# 设置 graphviz_dot_args 的参数,这里默认了默认字体
graphviz_dot_args = ['-Gfontname=Georgia', 
                     '-Nfontname=Georgia',
                     '-Efontname=Georgia']
# 输出格式,默认png,这里我用svg矢量图
graphviz_output_format = 'svg'

这里graphviz_dot的值是dot,为了不把绝对路径写到配置中,防止其他人的路径不一样,所以这里要求dot这个程序在环境变量中,能够直接使用。

graphviz_dot_args这个参数注意正确使用'-Gfontname=Microsoft YaHei',以下是错误的'-Gfontname="Microsoft YaHei"'。 通过-G, -N, -E 来设置全局的 graphnodeedge 属性。

开始使用Graphviz

好了,接下来就可以在sphinx文档中插入你的图片了。

例如:

.. graphviz::

    digraph abc{
        a;
        b;
        c;
        d;

        a -> b;
        b -> d;
        c -> d;
    }

demo图

简单的图形

或者通过

.. graphviz:: external.dot

这个使用一个dot文件内容。

测试一下你的graphviz能否支持好中文


.. graphviz::
   
   digraph idp_modules{
     fontname = "Microsoft YaHei";
     rankdir = TB;
     fontsize = 12;
     
     node [fontname = "Microsoft YaHei", fontsize = 12, shape = "record" ];
     edge [fontname = "Microsoft YaHei", fontsize = 12 ];
     
         subgraph cluster_sl{
             label="IDP支持层";
             bgcolor="mintcream";
             node [shape="Mrecord", color="skyblue", style="filled"];
             network_mgr [label="网络管理器"];
             log_mgr [label="日志管理器"];
             module_mgr [label="模块管理器"];
             conf_mgr [label="配置管理器"];
             db_mgr [label="数据库管理器"];
         };
     
         subgraph cluster_md{
             label="可插拔模块集";
             bgcolor="lightcyan";
             node [color="chartreuse2", style="filled"];
             mod_dev [label="开发支持模块"];
             mod_dm [label="数据建模模块"];
             mod_dp [label="部署发布模块"];
         };
     
     mod_dp -> mod_dev [label="依赖..."];
     mod_dp -> mod_dm [label="依赖..."];
     mod_dp -> module_mgr [label="安装...", color="yellowgreen", arrowhead="none"];
     mod_dev -> mod_dm [label="依赖..."];
     mod_dev -> module_mgr [label="安装...", color="yellowgreen", arrowhead="none"];
     mod_dm -> module_mgr [label="安装...", color="yellowgreen", arrowhead="none"];
   }

如果你的graphviz能够对上面的片段能够输出全部的中文,那么你的graphviz就对中文支持很好了。如图:

中文识别不太好

如果使用Windows的可能node节点里面的文字会看不见,而Linux下的graphviz可以工作的很好。

在中文label的前面增加一个空白字符,要使用以下的:

.. graphviz::
   
   digraph idp_modules{
     fontname = "Microsoft YaHei";
     rankdir = TB;
     fontsize = 12;
     
     node [fontname = "Microsoft YaHei", fontsize = 12, shape = "record" ];
     edge [fontname = "Microsoft YaHei", fontsize = 12 ];
     
         subgraph cluster_sl{
             label=" IDP支持层";
             bgcolor="mintcream";
             node [shape="Mrecord", color="skyblue", style="filled"];
             network_mgr [label=" 网络管理器"];
             log_mgr [label=" 日志管理器"];
             module_mgr [label=" 模块管理器"];
             conf_mgr [label=" 配置管理器"];
             db_mgr [label=" 数据库管理器"];
         };
     
         subgraph cluster_md{
             label=" 可插拔模块集";
             bgcolor="lightcyan";
             node [color="chartreuse2", style="filled"];
             mod_dev [label=" 开发支持模块"];
             mod_dm [label=" 数据建模模块"];
             mod_dp [label=" 部署发布模块"];
         };
     
     mod_dp -> mod_dev [label="依赖..."];
     mod_dp -> mod_dm [label="依赖..."];
     mod_dp -> module_mgr [label="安装...", color="yellowgreen", arrowhead="none"];
     mod_dev -> mod_dm [label="依赖..."];
     mod_dev -> module_mgr [label="安装...", color="yellowgreen", arrowhead="none"];
     mod_dm -> module_mgr [label="安装...", color="yellowgreen", arrowhead="none"];
   }

修正后,可以更好的支持中文了。

修正后,中文识别的更好

参考

分类: 实用技巧

Sublime Text预览Graphviz图

经常用Sublime Text来进行画Graphviz图,如果每次用命令行来进行预览就麻烦了。这个时候当然要利用热心的网友提供的插件了。

下载安装Graphviz

Windows下载Graphviz,解压到一个路径下,然后把其bin目录加入到环境变量中。在cmd中dot -V来验证是否可以使用dot编译了。

Linux请使用系统自带的包管理程序来安装atp-get install graphviz,和Windows同样的验证方法。

自动安装插件不兼容Windows

打开Package Control来搜索了一下graphviz,还真的发现了一个插件GraphvizPreview。于是安装它,发现并不能用。使用快捷键win + shift + g 出现

Graphviz: Could not open PDF, only works for Mac… fork this repo for your OS!’

什么情况,插件只能支持Mac,不支持Windows。

上官方的github的issue搜索看了下,有人已经提交了Windows版本的修复,可是Package Control的版本还是很老的,没有把master的版本进行更新。所以通过release版本下载的是2014年4月份的v0.1.1版本,而Windows的修复版本是在2015年2月份。

所以只能通过下载master来进行手动安装。

手动安装步骤

第一步:下载https://github.com/munro/SublimeGraphvizPreview/archive/master.zip 第二步:打开Preferences -> Packages Settings -> Packages Control -> Settings User,来确认一下installed_packages没有GraphVizPreview。并且增加"remove_orphaned": false防止Sublime Text 把手动安装的插件包给删除了。

{
    "bootstrapped": true,
    "in_process_packages":
    [
    ],
    "installed_packages":
    [
        "EncodingHelper",
        "Package Control",
        "Theme - Spacegray"
    ],
    "remove_orphaned": false
}

第三步:打开Preferences -> Browse Packages...进入到Sublime Text的插件包下Packagas

第四步:解压zip文件到Packagas下,并且更改文件夹SublimeGraphvizPreview-masterGraphVizPreview

第五步:重启Sublime Text。

效果图预览

参考

分类: 实用技巧

sudo保持前用用户的env环境变量

在虚拟机里安装了一个Ubuntu,在局域网下,需要设置代理才能访问网络和安装程序。很自然的给sudo vim /etc/bash.bashrc添加代理。

# 设置代理
export http_proxy=http://web-proxy.oo.com:8080
export https_proxy=http://web-proxy.oo.com:8080
export no_proxy=localhost,.oo.com,.local

然后很愉快的sudo apt-get update发现根本无法连接服务器。如果切换到sudo su的root用户下,是可以的执行的。

研究了半天,原来是sudo在切换成root用户的时候,env并不会去保留这些环境变量,需要特别的指明才可以。

通过visudo命令来设置,需要保留的环境变量,新增下面的第10行。Defaults env_keep="http_proxy https_proxy ftp_proxy no_proxy DISPLAY XAUTHORITY"。这样就可以继续愉快的访问网络了。

#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults        env_reset
Defaults        env_keep="http_proxy https_proxy ftp_proxy no_proxy DISPLAY XAUTHORITY"
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

友情提示。只能通过visudo命令来更新,不能修改/etc/sudoers文件,会被覆盖的。

分类: 未分类

发现一个漂亮的IDE皮肤spacegray

偶然经过WEB开发的座位,发现的他的编辑器很漂亮,问了一下是什么编辑器。原来是Sublime Text,求问是什么皮肤,回答是spacegray

Sublime Text 中的spacegray

sublime text spacegray theme

sublime text spacegray theme

个人在皮肤上做了一些设置。使得更适合我

{
    "color_scheme": "Packages/User/base16-eighties.dark (SL).tmTheme",
    "theme": "Spacegray.sublime-theme",

    "highlight_line": true,

    "spacegray_sidebar_font_xlarge": true,
    "spacegray_sidebar_tree_large": true,
    "spacegray_tabs_auto_width": true,
    "spacegray_tabs_font_large": true,
    "spacegray_tabs_xlarge": true,

    "line_padding_bottom": 3,
    "line_padding_top": 3
    ....
}

获取地址:http://kkga.github.io/spacegray/

jetbrains系列中的spacegray设置

spacegray-pycharm 经过我修改后的样式

spacegray-pycharm 经过我修改后的样式

我是从https://github.com/abhimanyusharma003/phpstorm-spacegray上面下载,并根据自己的喜好做了一些变化的。因为默认的颜色有的地方感觉不好看。

我的变更:

  • 当前光标行高亮
  • 选中文字颜色默认是白色,我把它去除了
  • 选中的背景色太亮,把它调的更灰一些。
  • 普通变量文字颜色太灰,和注释的一些灰,不好区分,调的更白色一些

我的配置设置下载myspacegray-pycharm.jar

另外还有一个ocean的皮肤我也觉得很漂亮,http://www.ideacolorthemes.org/themes/96/但是有些颜色也不容易区分。

从jar包导入配置的方法

jetbrains系列从jar包导入配置的方法。

  1. 选择编辑器FileImport Setting
  2. 重启
  3. 在设置中EditorColors and fonts,选择一个主题

分类: Programming

uwsgi python home设置

运行uwsgi,发现500错误,一看uwsgi的log。

ImportError: No module named random

一看就奇怪了,标准的python的类库,怎么就不支持呢?

一看原来以前的uwsgi配置里面有个,现在没有了。

./uwsgi ./uwsgi.ini -H /usr/local/services/python

增加一个PYTHONHOME的环境变量,

export PYTHONHOME=/usr/local/services/python

就可以把这个配置给取消了。

因为这个python不是标准的安装,所以这些都没有设置。

« 较早的 文章

Copyright © 2016 东东东 陈煜东的博客 粤ICP备13059639号-1

SITEMAP回到顶部 ↑