于仁颇黎 ROBOT PROGRAMMER

Integrate simditor to ROR project with image upload

最近在开发一个用于自己写技术文章的平台,需要有一个让自己快乐写作的编辑器,之前使用的是pagedown的编辑器,使用pagedown-bootstrap-rails这个gem可以很方便在在rails上集成一个比较漂亮的markdown编辑器,但是有一个问题,markdown这种语法度很高的写作语言,还大部分的流行在IT程序员当中,工业领域的工程师是相对比较传统的,习惯使用传统的编辑器,这让我萌生了更换编辑的想法,于是在ruby-china发了一个帖子有推荐一下好用的 Rails editor 吗?,社区大大力推荐我使用simditor,惊艳啊!于是立马迁移!

ROR的环境

  • 'rails', '4.1.8'
  • 'Ruby'. '2.1.5'
  • OSx 10.10.5

步骤

  1. Gemfile里面加入一行gem 'simditor'
  2. bundle install安装这个simditor这个gem,已经打包好所有simditor需要用的assets了
  3. application.js里面加上:

    //= require simditor
    //= require simditor/simditor-fullscreen
    

    注:我还加了一个simditor-fullscreen的插件,使用esc切换全屏,方法专注于写作

  4. application.css里面加上*= require simditor

  5. _form.html.erb可以这么写:

<div class="sky-form">
  <%= form_for(@post) do |f| %>
  <fieldset>
    <section>
      <label class="label"><strong><%= t('posts.title') %></strong></label>
      <label class="input"><%= f.text_field :title,placeholder: "这里输入标题..."%></label>
    </section>
    <section>
    <label class="label"><strong><%= t('posts.body') %></strong></label>
    <%= f.text_field :body, :type=> 'hidden'%>
    </section>
    <section>
    <label class="label"><strong>Tag</strong></label>
    <label class="input"><%= f.text_field :tag_list, placeholder: t('videos.tagshint') %></label>
    </section>
    <section class="pull-right">
    <%= f.submit t('posts.post'), :class => 'btn-u btn-lg' %>
    </section>
    </fieldset>
  <% end %>
  </div>
  <% end %>
 <script type="text/javascript">
var editor = new Simditor({
  textarea: $('#post_body'),
  toolbar: ['title', 'bold', 'italic', 'underline', 'strikethrough', 'color', '|', 'ol', 'ul', 'blockquote', 'code', 'table', 'link','image', '|','hr','indent','outdent','alignment','fullscreen'],
  placeholder: '这里输入文字...',
  pasteImage: true,
  fileKey: 'file',
  upload: {
    url: '/photos',
    params: null,
    connectionCount: 3,
    leaveConfirm: 'Uploading is in progress, are you sure to leave this page?'
  }
});
</script>

注:在text_field里面一定要加一个:type=> 'hidden',要不然会有另外一个input显示出来。

集成图片上传

我的方案是需要在写文章的时候上传图片,容易写图文混排的技术文章,步骤:

  1. 新建一个photosController.rb,写一个uploadaction用来处理图片上传
  2. 新建一个migration,创建一个photostable用来存储图片信息
  3. 新建一个photos.rb
  4. routes.rb里面加上图片上传的路由POSTpost 'photos' => 'photos#upload'
  5. 新建一个photo_uploader.rb,使用CarrierWave和MiniMagick用来处理文件上传和图片处理过程,需要两个gem:gem 'carrierwave','0.6.2'gem 'mini_magick'
  6. user.rb里面加入has_many :photos
  7. 相关代码如下:
# PhotosController.rb
class PhotosController < ApplicationController
    before_action :authenticate_user!
    def upload
        @photo = Photo.new
        @photo.image = params[:upload_file]
        @photo.user_id = current_user.id
        success = true
        msg = '上传成功'
        file_path = ''
        if @photo.save
            success=true
          render json: { :success=> success, :msg=>msg, :file_path=> @photo.image.url }
        else
            success=false
          render json: { :success=> false }
        end
    end
end
#Createphotos.rb
class CreatePhotos < ActiveRecord::Migration
  def change
    create_table :photos do |t|
      t.string :image
      t.timestamps
    end
    add_column :photos,:user_id,:integer
    add_index :photos, :user_id
  end
end
#photo.rb
class Photo< ActiveRecord::Base
 belongs_to :user
 validates :user_id, presence: true
 validates :image, presence: true
 mount_uploader :image, PhotoUploader
end
#photo_uploader.rb
class PhotoUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
  storage :file
  process resize_to_limit: [640, nil]
  def store_dir
    "photos/"
  end
  def filename
    if super.present?
      @name ||= Digest::MD5.hexdigest(current_path)
      "#{Time.now.year}/#{@name}.#{file.extension.downcase}"
    end
  end
  def extension_white_list
    %w(jpg jpeg gif png)
  end
end

阅读全文 »

布衣秋愁

布衣秋愁

一地杏黄一片秋,

一场细雨一般柔。

一纸词句一邂逅,

一袭布衣一点愁。

2015.11.20

阅读全文 »

在Ubuntu上用thin发布ROR应用

How to deploy ruby on rails with thin on Ubuntu

Create a deploy user

sudo adduser deploy
sudo adduser deploy sudo
su deploy

update and install packages

sudo apt-get update
sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties

Install RVM

sudo apt-get install libgdbm-dev libncurses5-dev automake libtool bison libffi-dev
curl -L https://get.rvm.io | bash -s stable
source ~/.rvm/scripts/rvm
echo "source ~/.rvm/scripts/rvm" >> ~/.bashrc
rvm install 2.1.5
rvm use 2.1.5 --default
ruby -v

echo "gem: --no-ri --no-rdoc" > ~/.gemrc

Git Server

RoR比较流行的是使用git,我们来配置一下Git Server,首先我们需要新建一个名为git的用户并且为它添加公钥。

$ sudo adduser git
$ sudo vi /home/git/.ssh/authorized_keys

我这里假设你的项目名称是project和准备把git仓库的目录设定为/opt/git,如果你没有一个/opt/git目录,需要切换到root新建并且把这个目录的所有者改为git:

$ su - root
# cd /opt
# mkdir git
# chown git git
$ cd /opt/git
$ mkdir project.git
$ cd project.git
$ git --bare init

本地电脑

$cd /git/project
$git remote add alt alt-machine:/path/to/repo
$git push alt master

这样会把本地项目同步到git server

Installing MySQL

sudo apt-get install mysql-server mysql-client libmysqlclient-dev

创建用户

CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON * . * TO 'newuser'@'localhost';
FLUSH PRIVILEGES;

更改用户密码

mysqladmin -u USER -p password NEWPASSWORD 

创建数据库

CREATE DATABASE database name;

mysql.sock

vi /etc/mysql/my.cnf
You will find the lines below top in your configuration file

[client]
port            = 3306
socket          = /var/run/mysqld/mysqld.sock

install thin

gem install thin    
thin config -C /etc/thin/myapp.example.com -c /var/www/myapp.example.com --servers 3 -e development # or: -e production for caching, etc

install nginx

sudo apt-get install nginx

nginx configuration

#/etc/nginx/sites-enabled/myapp.example.com
upstream myapp {
  server 127.0.0.1:3000;
  server 127.0.0.1:3001;
  server 127.0.0.1:3002;
}
server {
  listen   80;
  server_name .example.com;

  access_log /var/www/myapp.example.com/log/access.log;
  error_log  /var/www/myapp.example.com/log/error.log;
  root     /var/www/myapp.example.com;
  index    index.html;

  location / {
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header  Host $http_host;
    proxy_redirect  off;
    try_files /system/maintenance.html $uri $uri/index.html $uri.html @ruby;
  }

  location @ruby {
    proxy_pass http://myapp;
  }
}

ln -nfs /etc/nginx/sites-available/myapp.example.com /etc/nginx/sites-enabled/myapp.example.com

Start app

thin start -C ~/myapp.example.com 
/etc/init.d/nginx reload
/etc/init.d/nginx restart

用git更新项目

ps -aux
cd your_project_dir
git fetch https://github.com/xxx/yyy.git
git pull https://github.com/xxx/yyy.git
thin start -C ~/myapp.example.com 
/etc/init.d/nginx reload
/etc/init.d/nginx restart

阅读全文 »

工业机器人的价格正在下降

作者:Prof. Ilian Bonev 译者: brucebot

最近一周我在香港参加了一个工业机器人的会议,讨论关于中国正在加大力度推进机器人的本地化生产,在看了这些相关的PPT后,我忍不住想知道那几大主要的工业机器人生产商,会有什么样的反应。ABB,Fanuc,Kuka和Yaskawa会因此开始降价吗?2013年,安装在中国的机器人中,有近1/4近37,000套工业机器人,是由本地制造商制造的(IFR 数据), 同这个数量还在不断的增加。但是,这些主要的机器人厂商面对的威胁,并不仅仅来自于诸如深圳,上海和广州,这几个中国主要的工业机器人工业相对发达的城市,他们面对的威胁来自于全世界。

GSK

制造一台工业机器人并不容易,但是也不见得与发射火箭一样难,至少要比制造一辆汽车来是简单的多了。一些优秀的机器人专家,一些投资,几年的努力工作,足够完成一台工业机器人的设计,并且实际的制造出来,这对当前一些工业发达的领导者来说,这些都不是一个问题。虽然这可以帮助KUKA减少一些市场推广的预算,但是机器人并不是昂贵的产品,关于机器人的的事情,在现在这个时候,传播的非常快。

Universal Robots显然已经不再是以前刚开始时候的Startup小公司了,虽然与其他大型的工业机器人制造商来说,还是很小。但是,这并不妨碍他在去年得到的比其他工业机器人厂商更多的注意(如果我们不考虑KUKA的乒乓球大赛的话 :)),同时他们的销售数量开始接其他同类型号的工业机器人。

AUTOMATICAL 2014的开幕式上,KUKA的LBR iiwa轻量型工业机器人,又有了一个新的竞争对手: the Roberta collaborative robot arm. Roberta是由gometec(之前称为 RG Mechatronics),一家小型的德国公司开发。Gomtec与KUKA的LBR iiwa一样,都根源说德国宇航局(DLR)下属的机器人与机械电子研究院。 这家公司由前DLR机器人研究员Bernd Gombert(下图)所有,他是公认的轻量级工业机器人研究的重要人物,也是SpaceMouse的发明者。事实上,Roberta是6个不同的机器人系列的一种,在增加了所有可能的辅助配置后,它的价格要比最近降价很多的两款KUKA LBR iiwa还要低的多,我估计是最后一个因为喜爱而发了$200,000买了这个机器人的人了。

Roberta

一天之前,在ICRA 2014上,一家由来自田纳西大学的Tan Jindong教授领导的初创公司Somkie Robotics,发布了一款令我相当惊讶的UR5工业机器人,价格只需要$15,000 !!事实上这款机器人名为了OUR-1(开发单元机器人)在中国制造,当然它没有真实的UR5,UR10的安装功能,也没有UR系统的漂亮的用户界面,没有UR的示教演示功能,但是看起来,制造的相当不错。当然,这款OUR-1机器人,无法与UR5相比,但是它仍然很有市场。比如说我,就愿意去买一台。Universal Robot刚刚发布消息,说已经开始在UR机器人部署绝对编码器(OUR-1已经安装有绝对编码器了),如果下一步UR要开始降价,我也绝对不会感到奇怪了。

OUR-1

中国与这些来自世界其他地区的新兴的充满活力的初创企业快速发展,并且随着市场需求的不断增加,那些工业机器人领导者们将会慢慢的开始降价。不过,现在,他们更需要担心的是,当公众相信:机器人不会抢走现在工人的工作

阅读全文 »

配置Apple TV同时看国内和国外视频

先说一下,我已经有好试过好几种方法用来在电视上看视频,最开始是装了一个HTPC,接着入了android Mini PC,然后用了一个pi安装xbmc,再最后LETV出来了C1,就买了一个,不过,这些方法都有一些不足。HTPC的耗电厉害,而且开机时间很长,因为跑的是windows 7;android Mini PC的界面很差,操作非常不友好;pi下面的xbmc相对好一点,但是如果需要看国内的视频,界面非常不友好,不利于操作。

于是,我买了一个Apple TV.Air Play自不用说,于Macbook,iphone等都配合的非常好,甚至还可以镜像过去,或者成为Mac的延伸桌面。但是作为一个看电视的设备,看国内与国外视频,还是最为关键的,于是有了两个办法。

国内视频

直接更改Apple TV的DNS,最为有名就是盒子大师,具体方法是劫持Apple TV里面的预告片,达到Apple TV观看国内网络的视频,目前搜狐、优酷、乐视等,据说还可以架设自已的视频源,不过这部分我还没有尝试,我更想自己搭建一个自己的DNS,放在我的Pi上,这样的速度会更好,目前找到的参考方法是使用Plex,参考文章:https://langui.sh/2013/08/27/appletv-ssl-plexconnect/

注意:新的Apple TV系统升级后,设置——通用——描述文件里添加描述文件,输入http://t.cn/zRLJ6Js(务必注意大小写).

国外视频

这个有两种方法,一种是使用PAC代理,还有一种是使用VPN,使用这两种方法,都需要有一个软件Apple Configurator,目前这个软件只支持MAC版本.Windows下有一个iPhone 配置实用工具,不过我没有用过。

  1. 如果只想看Youtube,而又想比较有速度的看国内视频,则使用PAC。我最推荐PAC代理,这样的话,不用让所有的流量都走VPN,至于怎么样得到PAC代理,你购买APN或者自己搭建一个APN。

  2. 如果想看US ONly的视频,比如HBO GO,Netfilx等,则使用VPN,全局流量全部走US的VPN的,就能破解US Location Limit的服务了。

完成Apple TV初始设置后,打开apple TV插入mini USB,注意开机后插入,指示灯不闪烁。打开Apple Configurator,安装描述文件,在wifi设置里面填上家里的无线SSID名称,密码,代理设置里面填上PAC地址;VPN的话,填上VPN相关的信息就可以,支持的VPN种类很多,L2tp/PPTP,anyconnect等都支持。

Apple TV Wifi PAC设置

注意:安装好后,查看国内视频的功能可能会失效,需要重新设置一下国内视频里面的描述文件。

OK.Enjoy!!

阅读全文 »

工业机器人技术维基更新

考虑到工业机器人知识查找的麻烦,为roboticsfaq.com增加了维基的功能,每一个人均可以去编辑,或增加内容,或修改错误,并且系统会记录更改的作者与更改的日期。

Roboticsfaq wiki

Roboticsfaq wiki details

另外,主页也更新了一下Roboticsfaq.com的主页,增加了显示社区最新的主题,最热的视频与论文及最近的技术维基,方便一进入就能看到更多的信息,希望这些功能可以方便工程师。

Roboticsfaq new home page

阅读全文 »

个人隐私泄露给骗子带来成功

事情是这样的,前几天通过中国国航的手机app订了一张与深圳航空代码共享的航班,不料在出发前几日收到一条这样的短信:

尊敬的旅客,您所预订03月xx日深圳航空ZHxxxx航班,已被管制禁止起飞,收到短信后,请及时联系本次航班处理服务热线:**4008-557-155**办理退票或改签【深航】

短信发送的号码是:10690290007750

收到短信后,我立马打了国航的服务电话95583,告知他帮我确认一下这个航班的情况,是否真的如短信中所说已经取消,需要办理退票手续。话务员在多方确认之后,告诉我这个航班正常了,于是我就不理会这条短信了。

回到家,还是不放心,去垃圾电话查询了发给秘短信的号码10690290007750和,短信里面留的电话4008-557-155,均没有信息,于是我转向 12321网络不良与垃圾信息举报受理中心,可惜的是这个网站,并没有一个查询一个电话是否为垃圾电话的功能,右边的查询只是查询你的举报是否有效,FUCK!

于是我把方向转向Google,当我以关键字“深圳航空 诈骗短信”在Google搜索的时候,发现了意想不到的信息,这个诈骗从2013年10月份开始就有了,方法如出一辙,受害人无数。

Google搜索深圳航空诈骗短信

天涯的一篇深航内部泄露乘客信息给诈骗分子,亲身经历,大家引以为戒,发布时间是“2013-10-16 10:39:00 点击:1234“,还有21CN的一篇多家航空公司遮盖的丑闻:客户信息泄露近半年,有人被诈骗11万多元发布于2014-03-07 17:59:37。

我又转向深圳航空的官方网站,也看到了一篇发布于2013年11月12日的关于再次提醒防范欺诈短信的公告.

关于再次提醒防范欺诈短信的公告

同样的深圳航空手机app也同样有类似的防诈骗提醒.

深圳航空app防诈骗提醒

@深圳航空 的网站再次提醒公告时间是2013年11月12日,我是前几天定的航班,也同样收到这样的诈骗短信,也就是意味着@深圳航空 的信息泄露从2013年10月到现在2014年3月,还在进行中,这5个月来@深圳航空做了什么?几乎是什么都没有做吧?我并非通过第三方定的机票,而是通过@中国国际航空 的官方app定的航班,从多方的信息中判断,信息泄露只能是深圳航空官方了,我想说FUCK!

阅读全文 »