• Posts tagged "github"

Blog Archives

R包开发每日中国天气

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-package-chinaweather/

r-package-chinaweather

前言

本节将继续R语言天气可视化应用一文的内容,把我们已经完成的R语言程序,封装成R语言程序包。这个看起来简单的任务,其实要花很多的时间来处理细节。整个的R包开发过程,将按照文章在巨人的肩膀前行 催化R包开发的流程进行,为了保证check()函数的顺利执行,代码有多处改动。

目录

  1. 构建项目
  2. 静态数据
  3. 编写功能代码
  4. 项目配置文件
  5. 调试程序
  6. 程序打包

1. 构建项目

R语言天气可视化应用一文,我们写的R程序都在Window中完成,由于R的跨平台代码有兼容性的问题,我们的应用程序最终将在Linux中发布,所以为了减少发布时不必要的麻烦,我们转到Linux系统中完成R包的开发。

本节的系统环境

  • Linux: Ubuntu Server 12.04.2 LTS 64bit
  • R: 3.1.1 x86_64-pc-linux-gnu (64-bit)
  • RStudio-Server 0.97.551

在巨人的肩膀前行 催化R包开发文中,我们其实已经创建好了chinaWeather项目,那么R包的开发将继续在这个项目中进行。进入chinaWeather项目的目录,我单独开一个Git分支,进行本节的R包开发。


~ cd /home/conan/R/chinaWeather     # 进入项目目录
~ git branch app                    # 新建分支,名为app
~ git checkout app                  # 切换到分支app
~ git branch                        # 查看当查的分支
  * app
    master

查看Linux系统中,R语言环境变量的设置,字符集是特别要处理的部分。


> sessionInfo()
R version 3.1.1 (2014-07-10)
Platform: x86_64-pc-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
 [3] LC_TIME=zh_CN.UTF-8        LC_COLLATE=en_US.UTF-8
 [5] LC_MONETARY=zh_CN.UTF-8    LC_MESSAGES=en_US.UTF-8
 [7] LC_PAPER=zh_CN.UTF-8       LC_NAME=C
 [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=zh_CN.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

环境准备就绪,下面就是开始R包开的工作了。

2. 静态数据

在开始写R包代码之前,我们需要先来整理一下静态数据。 这个项目中,静态数据包括了地图数据、WOEID映射数据、天气概况的映射数据、中英文图片可视化数据、测试数据集。对于普通的R应用程序来说可以用CSV格式文件保存在本地,但对于R包项目来说,最好是封装成rda的数据文件,随R包一起打包发布。

首先,我们就要对这些静态数据文件进行整理,新建目录metadata,用于存储原始CSV文件和地图文件。


~ mkdir /home/conan/R/chinaWeather/metadata         # 新建目录,并把原数据文件复制到metadata目录
~ ls -l /home/conan/R/chinaWeather/metadata         # 查看metadata目录
-rw-rw-r-- 1 conan conan 3396 10月  4 22:14 20141001.csv         # 测试数据集
-rw-r--r-- 1 conan conan  754  2月  5  2013 ADCODE99.csv         # ADCODE99与省份中文映射数据
-rw-r--r-- 1 conan conan 1418  2月  6  2013 code.csv             # 天气概况映射数据
-rw-r--r-- 1 conan conan  214  2月  6  2013 labelcode.csv        # 天气概况映射数据
drwxr-xr-x 2 conan conan 4096  4月 23  2013 mapdata              # 地图数据目录
-rw-rw-r-- 1 conan conan 1900  2月  4  2013 WOEID.csv            # WOEID映射数据

~ ls -l /home/conan/R/chinaWeather/metadata/mapdata     # 查看地图数据文件
-rw-r--r-- 1 conan conan   86283  4月 10  1999 bou2_4p.dbf
-rw-r--r-- 1 conan conan 1508752  4月 10  1999 bou2_4p.shp
-rw-r--r-- 1 conan conan    7500  4月 10  1999 bou2_4p.shx

把静态数据转换为rda格式的文件,存储在data目录中。


~ mkdir /home/conan/R/chinaWeather/data       # 新建目录data
~ R                                           # 启动R语言程序。

2.1 WOEID数据文件 WOEID.rda

对WOEID数据进行处理,把adcode99代码合并到WOEID数据集中,合并WOEID.csv文件和ADCODE99.csv文件的数据,生成WOEID.rda的文件。


> WOEID<-read.csv(file="metadata/WOEID.csv",header=FALSE,fileEncoding="utf-8", encoding="utf-8")     # 加载WOEID数据集
> names(WOEID)<-c("en","woeid","zh",'prov','long','lat')
> adcode99<-read.csv(file="metadata/ADCODE99.csv",header=TRUE,fileEncoding="utf-8", encoding="utf-8")     # 加载ADCODE99数据集

> fc<-function(row){
+     code<-adcode99$ADCODE99[which(row[4]==as.character(adcode99$prov))]
+     if(length(code)==0)code=0
+     code
+ }
> WOEID<-cbind(WOEID,adcode99=unlist(apply(WOEID,1,fc)))                # 合并数据集
> save(WOEID,file="data/WOEID.rda")                                     # 生成WOEID.rda文件

> WOEID     # 合并后的WOEID数据集
               en    woeid       zh             prov      long      lat adcode99
  1       beijing  2151330     北京           北京市 116.46667 39.90000   110000
  2      shanghai  2151849     上海           上海市 121.48333 31.23333   310000
  3        tianji  2159908     天津           天津市 117.18333 39.15000   120000
  4     chongqing 20070171     重庆           重庆市 106.53333 29.53333   500000
  5        harbin  2141166   哈尔滨         黑龙江省 126.68333 45.75000   230000
  6     changchun  2137321     长春           吉林省 125.31667 43.86667   220000
  7      shenyang  2148332     沈阳           辽宁省 123.40000 41.83333   210000
  8        hohhot  2149760 呼和浩特     内蒙古自治区 111.80000 40.81667   150000
  9  shijiazhuang  2171287   石家庄           河北省 114.46667 38.03333   130000
  10     wulumuqi 26198317 乌鲁木齐 新疆维吾尔自治区  87.60000 43.80000   650000
  11      lanzhou  2145605     兰州           甘肃省 103.81667 36.05000   620000
  12       xining  2138941     西宁           青海省 101.75000 36.63333   630000
  13         xian  2157249     西安           陕西省 108.90000 34.26667   610000
  14     yinchuan  2150551     银川   宁夏回族自治区 106.26667 38.33333   640000
  15    zhengzhou  2172736     郑州           河南省 113.70000 34.80000   410000
  16        jinan  2168327     济南           山东省 117.00000 36.63333   370000
  17      taiyuan  2154547     太原           山西省 112.56667 37.86667   140000
  18        hefei  2127866     合肥           安徽省 117.30000 31.85000   340000
  19        wuhan  2163866     武汉           湖北省 114.35000 30.61667   420000
  20     changsha 26198213     长沙           湖南省 113.00000 28.18333   430000
  21      nanjing  2137081     南京           江苏省 118.83333 32.03333   320000
  22      chengdu  2158433     成都           四川省 104.08333 30.65000   510000
  23      guiyang  2146703     贵阳           贵州省 106.70000 26.58333   520000
  24      kunming  2160693     昆明           云南省 102.68333 25.00000   530000
  25      nanning  2166473     南宁   广西壮族自治区 108.33333 22.80000   450000
  26         lasa 26198235     拉萨       西藏自治区  91.16667 29.66667   540000
  27     hangzhou  2132574     杭州           浙江省 120.15000 30.23333   330000
  28     nanchang 26198151     南昌           江西省 115.86667 28.68333   360000
  29    guangzhou  2161838     广州           广东省 113.25000 23.13333   440000
  30       fuzhou  2139963     福州           福建省 119.30000 26.08333   350000
  31       taipei  2306179     台北           台湾省 121.51667 25.05000   710000
  32       haikou  2162779     海口           海南省 110.33333 20.03333   460000
  33     hongkong 24865698     香港   香港特别行政区 114.16667 22.30000   810000
  34        macau 20070017     澳门   澳门特别行政区 113.50000 22.20000        0

我们看到WOEID数据集包括了中文字符,而R语言的rda的规范中,要求不能包括ASCII以外的字符集了。在执行check()检查的过程中,就会遇到非法字符集的警告错误。因此,就需要对中文数据集进行特殊转码处理,把中文字符统一转码成unicode来表示,如 北京 unicode转码后表示为 \u5317\u4eac。当数据集用于中文显示的时候,需要再反转unicode到中文,这样就可以中文与R语言程序的兼容了。

对WOEID的数据集转码处理,我们需要用到stringi包。


> install.packages("stringi")     # 安装stringi包
> library("stringi")              # 加载stringi包

通过 stri_escape_unicode()函数,对WOEID数据集的zh和prov列的中文进行unicode转码。


> WOEID$prov<-stri_escape_unicode(WOEID$prov)       # 对WOEID$prov列转码
> WOEID$zh<-stri_escape_unicode(WOEID$zh)           # 对WOEID$zh列转码
> save(WOEID,file="data/WOEID.rda",compress=TRUE)    # 保存数据集

> head(WOEID)            # 查看转码后的WOEID数据集
         en    woeid                          zh                                 prov     long      lat adcode99 adcode99
1   beijing  2151330          \\u5317\\u4eac          \\u5317\\u4eac\\u5e02 116.4667 39.90000   110000   110000
2  shanghai  2151849          \\u4e0a\\u6d77          \\u4e0a\\u6d77\\u5e02 121.4833 31.23333   310000   310000
3    tianji  2159908          \\u5929\\u6d25          \\u5929\\u6d25\\u5e02 117.1833 39.15000   120000   120000
4 chongqing 20070171          \\u91cd\\u5e86          \\u91cd\\u5e86\\u5e02 106.5333 29.53333   500000   500000
5    harbin  2141166 \\u54c8\\u5c14\\u6ee8 \\u9ed1\\u9f99\\u6c5f\\u7701 126.6833 45.75000   230000   230000
6 changchun  2137321          \\u957f\\u6625          \\u5409\\u6797\\u7701 125.3167 43.86667   220000   220000

我们再试一下,把unicode的数据转码成原来的中文字符,通过stri_unescape_unicode()函数实现。


> head(stri_unescape_unicode(WOEID$prov))
[1] "北京市"   "上海市"   "天津市"   "重庆市"   "黑龙江省" "吉林省"

> head(stri_unescape_unicode(WOEID$zh))
[1] "北京"   "上海"   "天津"   "重庆"   "哈尔滨" "长春"

转码的操作正常,所以在遇到非ASCII的字符集,我们就可以用这种方式进行转换了。

2.2 地图数据文件 chinaMap.rda

对地图数据进行处理,加载原始地图数据,生成chinaMap.rda文件。在chinaMap对象中,NAME列也是中文字符,但Linux系统在加载地图数据时,字符编码已经被修改,我们不能看到编码类型,所以这里不能通过上面所说的unicode转码。NAME列数据,我们刚好用不到,一种简单的操作方法就是将他从数据集中去掉。


> library(maps)
> library(mapdata)
> library(maptools)
> chinaMap<-readShapePoly('metadata/mapdata/bou2_4p.shp')       # 加载地图数据

> head(chinaMap$NAME)                       # NAME列,非ASCII编码
[1] \xba\xda\xc1\xfa\xbd\xadʡ
[2] \xc4\xda\xc3ɹ\xc5\xd7\xd4\xd6\xce\xc7\xf8
[3] \xd0½\xaeά\xce\xe1\xb6\xfb\xd7\xd4\xd6\xce\xc7\xf8
[4] \xbc\xaa\xc1\xd6ʡ
[5] \xc1\xc9\xc4\xfeʡ
[6] \xb8\xca\xcb\xe0ʡ
33 Levels: \xb0\xb2\xbb\xd5ʡ ... \xd6\xd8\xc7\xec\xca\xd0

> chinaMap<-chinaMap[,c(1:6)]              # 去掉NAME列
> save(chinaMap,file="data/chinaMap.rda",compress='xz')          # 生成chinaMap.rda文件

2.3 中英文图片可视化数据 props.rda

对于可视化的图片输出时,用于中文名的字段显示,生成props.rda文件,中文编码通过转成unicode进行处理。


> props<-data.frame(
+     key=c('high','low'),
+     zh=c('中国各省白天气温','中国各省夜间气温'),
+     en=c('Daytime Temperature','Nighttime Temperature')
+ )
> props$zh<-stri_escape_unicode(props$zh)
> save(props,file="data/props.rda",compress=TRUE)

2.4 测试数据集weather20141001.rda

以2014年10月01日的天气数据集,做为一个demo数据集,生成weather20141001.rda文件,中文编码通过转成unicode进行处理。


> weather20141001<-read.csv(file="metadata/20141001.csv",header=TRUE,fileEncoding="utf-8", encoding="utf-8")  # 加载数据庥
> weather20141001$prov<-stri_escape_unicode(weather20141001$prov)          # 对weather20141001$prov列转码
> weather20141001$zh<-stri_escape_unicode(weather20141001$zh)              # 对weather20141001$zh列转码
> save(weather20141001,file="data/weather20141001.rda",compress=TRUE)      # 生成weather20141001.rda文件。

查看data目录下面的文件列表,生成了4个静态数据集文件。


> dir('data')
[1] "WOEID.rda"   "chinaMap.rda"   "props.rda"  "weather20141001.rda"

我们把所有的静态数据集先整理好,下面的R包代码,就可以直接使用这些静态数据集了。

3. 编写功能代码

按照函数功能的不同,我们定义4个文件来描述这些函数。

  • getData.R,用于定义爬去数据的函数。
  • render.R,用于静态图片可视化渲染的函数。
  • chinaWeather.R,用于定义各种工具函数。
  • chinaWeather-packages.R,用于定义R包内的数据集。

3.1 文件 getData.R

新建文件getData.R,用于爬取数据和XML文档解析,文件中定义了3个函数。

  • getWeatherFromYahoo(), 从Yahoo的开放数据源,获取天气数据。
  • getWeatherByCity(), 通过城市英文名,获取当前城市的天气数据。
  • getWeather(), 获取中国省会城市的天气数据,在WOEID数据集中定义的城市。

~ vi R/getData.R

#' Get weather data from Yahoo openAPI.
#'
#' @importFrom RCurl getURL
#' @importFrom XML xmlTreeParse getNodeSet xmlGetAttr
#' @param woeid input a yahoo woeid
#' @return data.frame weather data
#' @keywords weather
#' @export
#' @examples
#' \dontrun{
#'  getWeatherFromYahoo()
#'  getWeatherFromYahoo(2151330)
#' }
getWeatherFromYahoo<-function(woeid=2151330){
  url<-paste('http://weather.yahooapis.com/forecastrss?w=',woeid,'&u=c',sep="")
  doc = xmlTreeParse(getURL(url),useInternalNodes=TRUE)

  ans<-getNodeSet(doc, "//yweather:atmosphere")
  humidity<-as.numeric(sapply(ans, xmlGetAttr, "humidity"))
  visibility<-as.numeric(sapply(ans, xmlGetAttr, "visibility"))
  pressure<-as.numeric(sapply(ans, xmlGetAttr, "pressure"))
  rising<-as.numeric(sapply(ans, xmlGetAttr, "rising"))

  ans<-getNodeSet(doc, "//item/yweather:condition")
  code<-as.numeric(sapply(ans, xmlGetAttr, "code"))

  ans<-getNodeSet(doc, "//item/yweather:forecast[1]")
  low<-as.numeric(sapply(ans, xmlGetAttr, "low"))
  high<-as.numeric(sapply(ans, xmlGetAttr, "high"))

  print(paste(woeid,'==>',low,high,code,humidity,visibility,pressure,rising))
  return(as.data.frame(cbind(low,high,code,humidity,visibility,pressure,rising)))
}

#' Get one city weather Data.
#'
#' @param en input a English city name
#' @param src input data source
#' @return data.frame weather data
#' @keywords weather
#' @export
#' @examples
#' \dontrun{
#'  getWeatherByCity()
#'  getWeatherByCity(en="beijing")
#' }
getWeatherByCity<-function(en="beijing",src="yahoo"){
  woeid<-getWOEIDByCity(en)
  if(src=="yahoo"){
    return(getWeatherFromYahoo(woeid))
  }else{
    return(NULL)
  }
}

#' Get all of city weather Data.
#'
#' @param lang input a language
#' @param src input data source
#' @return data.frame weather data
#' @keywords weather
#' @export
#' @examples
#' \dontrun{
#'  getWeather()
#' }
getWeather<-function(lang="en",src="yahoo"){
  cities<-getCityInfo(lang)
  wdata<-do.call(rbind, lapply(cities$woeid,getWeatherFromYahoo))
  return(cbind(cities,wdata))
}

3.2 文件 render.R

新建文件render.R,用于数据处理和静态图片可视化渲染,文件中定义了5个函数。

  • getColors(),用于根据天气情况匹配不同的颜色
  • drawBackground(),画出背景
  • drawDescription(),画出文字描述
  • drawLegend(),画出图例
  • drawTemperature(),画出气温及地图结合

~ vi R/render.R

#' match the color with ADCODE99.
#'
#' @param temp the temperature
#' @param breaks cut the numbers
#' @return new color vector
#' @keywords color
getColors<-function(temp,breaks){
  f=function(x,y) ifelse(x %in% y,which(y==x),0)
  colIndex=sapply(chinaMap$ADCODE99,f,WOEID$adcode99)

  arr <- findInterval(temp, breaks)
  arr[which(is.na(arr))]=19
  return(arr[colIndex])
}

#' Draw the background.
#'
#' @param title the image's title
#' @param date the date
#' @param lang the language zh or en
drawBackground<-function(title,date,lang='zh'){
  text(100,58,title,cex=2)
  text(105,54,format(date,"%Y-%m-%d"))
  #text(98,65,paste('chinaweatherapp','http://apps.weibo.com/chinaweatherapp'))
  #text(120,-8,paste('provided by The Weather Channel',format(date, "%Y-%m-%d %H:%M")),cex=0.8)
}

#' Draw the description.
#'
#' @importFrom stringi stri_unescape_unicode
#' @param data daily data
#' @param temp the temperature
#' @param lang the language zh or en
drawDescription<-function(data,temp,lang='zh'){
  rows<-1:nrow(data)
  x<-ceiling(rows/7)*11+68
  y<-17-ifelse(rows%%7==0,7,rows%%7)*3
  fontCols<-c("#08306B","#000000","#800026")[findInterval(temp,c(0,30))+1]
  if(lang=='zh'){
    txt<-stri_unescape_unicode(data$zh)
    text(x,y,paste(txt,temp),col=fontCols)
  }else{
    text(x,y,paste(data$en,temp),col=fontCols)
  }
  #text(x,y,bquote(paste(.(data$en),.(temp),degree,C)),col=fontCols)
}

#' Draw the legend.
#'
#' @param breaks cut the numbers
#' @param colors match the color
drawLegend<-function(breaks,colors){
  breaks2 <- breaks[-length(breaks)]
  par(mar = c(5, 0, 15, 10))
  image(x=1, y=0:length(breaks2),z=t(matrix(breaks2)),col=colors[1:length(breaks)-1],axes=FALSE,breaks=breaks,xlab="",ylab="",xaxt="n")
  axis(4, at = 0:(length(breaks2)), labels = breaks, col = "white", las = 1)
  abline(h = c(1:length(breaks2)), col = "white", lwd = 2, xpd = FALSE)
}

#' Draw temperature picture.
#'
#' @importFrom RColorBrewer brewer.pal
#' @importFrom stringi stri_unescape_unicode
#' @import maptools
#' @param data daily data
#' @param lang language
#' @param type low or high
#' @param date the date
#' @param output output a file or not
#' @param path image output position
#' @export
drawTemperature<-function(data,lang='zh',type='high',date=Sys.time(),output=FALSE,path=''){
  colors <- c(rev(brewer.pal(9,"Blues")),"#ffffef",brewer.pal(9,"YlOrRd"),"#500000")
  breaks=seq(-36,44,4)

  if(type=='high') {
    temp<-data$high
    ofile<-paste(format(date,"%Y%m%d"),"_day.png",sep="")
  }else{
    temp<-data$low
    ofile<-paste(format(date,"%Y%m%d"),"_night.png",sep="")
  }

  if(lang=='zh'){
    title<-stri_unescape_unicode(props[which(props$key=='high'),]$zh)
  }else{
    title<-props[which(props$key=='high'),]$en
  }

  if(output)png(filename=paste(path,ofile,sep=''),width=600,height=600)

  layout(matrix(data=c(1,2),nrow=1,ncol=2),widths=c(8,1),heights=c(1,2))
  par(mar=c(0,0,3,10),oma=c(0.2,0.2,0.2,0.2),mex=0.3)
  plot(chinaMap,border="white",col=colors[getColors(temp,breaks)])
  points(data$long,data$lat,pch=19,col=rgb(0,0,0,0.3),cex=0.8)

  drawBackground(title,date,lang)
  drawDescription(data,temp,lang)
  drawLegend(breaks,colors)
}

3.3 文件 chinaWeather.R

修改文件chinaWeather.R,用于定义各种工具函数,文件中定义了3个函数。

  • filename(),根据日期定义文件名称。
  • getWOEIDByCity(),通过城市名获得WOEID代码。
  • getCityInfo(),查看所有城市的信息,在WOEID数据集中定义的城市。

#' Define a filename from current date.
#'
#' @param date input a date type
#' @return character a file name
#' @keywords filename
#' @export
#' @examples
#' \dontrun{
#'  filename()
#'  filename(as.Date("20110701",format="%Y%m%d"))
#' }
filename<-function(date=Sys.time()){
  paste(format(date, "%Y%m%d"),".csv",sep="")
}

#' Get WOEID of Yahoo By City Name
#'
#' @param en input a English city name
#' @return integer WOEID
#' @keywords WOEID
#' @export
#' @examples
#' \dontrun{
#'  getWOEIDByCity()
#'  getWOEIDByCity(en="beijing")
#' }
getWOEIDByCity<-function(en="beijing"){
  return(WOEID$woeid[which(WOEID$en==en)])
}

#' Get all of city info
#'
#' @param lang input a language
#' @return data.frame city info
#' @keywords language
#' @export
#' @examples
#' \dontrun{
#'  getCityInfo()
#'  getCityInfo(lang="en")
#'  getCityInfo(lang="zh")
#' }
getCityInfo<-function(lang="en"){
  if(lang=="en")return(WOEID[-c(3,4)])
  if(lang=="zh")return(WOEID[-c(4)])
}

3.4 文件 chinaWeather-package.R

新建文件chinaWeather-package,用于定义R包的说明和内置数据集。

  • NULL,关于chinaWeather包的定义说明
  • 'WOEID',WOEID数据集的描述
  • 'chinaMap',chinaMap数据集的描述
  • 'props',props数据集的描述
  • 'weather20141001',weather20141001数据集的描述

#' China Weather package.
#'
#' a visualized package for china Weather
#'
#' @name chinaWeather-package
#' @aliases chinaWeather
#' @docType package
#' @title China Weather package.
#' @keywords package
NULL

#' The yahoo code for weather openAPI.
#'
#' @name WOEID
#' @description The yahoo code for weather openAPI.
#' @docType data
#' @format A data frame
#' @source \url{https://developer.yahoo.com/geo/geoplanet/guide/concepts.html}
'WOEID'

#' China Map.
#'
#' @name chinaMap
#' @description China Map Dataset.
#' @docType data
#' @format A S4 Object.
'chinaMap'

#' Charset for Chinease and English.
#'
#' @name props
#' @description Charset.
#' @docType data
#' @format A data frame
'props'

#' Dataset for 20141001.
#'
#' @name weather20141001
#' @description A demo dataset.
#' @docType data
#' @format A data frame
#' @source \url{http://weather.yahooapis.com/forecastrss?w=2151330}
'weather20141001'

4. 项目配置文件

我们在chinaWeather项目中,增加了好几个函数定义,同时增加了5包的依赖,那么项目配置文件也需要做相当的修改。

需要修改的文件有3个。

  • DESCRIPTION,项目描述文件,用于项目全局的配置。
  • NAMESPACE,命令空间文件,用于函数的访问权限控制。
  • .Rbuildignore,在打包时,用于排除不参与打包的文件。

4.1 修改文件 DESCRIPTION

DESCRIPTION文件,用于全局项目配置,在Imports选项中定义了5个包的依赖,并增加LazyData的选项。


Package: chinaWeather
Type: Package
Title: a visualized package for china Weather
Version: 0.1
Authors@R: "Dan Zhang  [aut, cre]"
Description: a visualized package for china Weather
Depends:
    R (>= 3.1.1)
Imports:
    RCurl,
    XML,
    maptools,
    RColorBrewer,
    stringi
LazyData: TRUE
License: GPL-2
Date: 2014-09-28

4.2 修改文件 NAMESPACE

NAMESPACE文件用于函数的访问控制,我们先手动定义需要输出的函数用,稍后在运行roxygen2包的document()函数,NAMESPACE文件会自动更新。


export(drawTemperature)
export(filename)
export(getCityInfo)
export(getWOEIDByCity)
export(getWeather)
export(getWeatherByCity)
export(getWeatherFromYahoo)

4.3 新建文件 .Rbuildignore

在打包的时候,可以排除不相关的文件,比如 metadata目录 和 .gitignore文件等。


.gitignore
dist
metadata
^.*\.Rproj$
^\.Rproj\.user$
README*
NEWS*
FAQ*

我们把R语言代码、函数注释和配置文件,都修改完成了,下面开始调试程序。

5. 调试程序

用devtools包的工具函数,调试程序还是比较简单的。


> library(devtools)     # 加载devtools包
> load_all("/home/conan/R/chinaWeather")        # 加载chinaWeather项目
Loading chinaWeather

> data(package="chinaWeather")                  # 查看chinaWeather的数据集
Data sets in package ‘chinaWeather’:
WOEID
chinaMap
props
weather20141001

调用weather20141001测试数据集,画出2014年10月01日的白天气温静态图。


> date<-as.Date(as.character(20141001), format = "%Y%m%d")
> drawTemperature(weather20141001,date=date)

w8

再画出2014年10月01日的英文的夜间气温图。


> drawTemperature(weather20141001,type='low',date=date,lang='en')

w9

生成的可视化图片,完成符合我们的要求。这里偷懒一下,暂时跳过单元测试了。之前我们在代码上已经加了注释,接下就通过roxygen2包生成文档。


> library(roxygen2)
> roxygenize("/home/conan/R/chinaWeather")
First time using roxygen2 4.0. Upgrading automatically...
Writing NAMESPACE
Writing chinaWeather-package.Rd
Writing WOEID.Rd
Writing chinaMap.Rd
Writing props.Rd
Writing weather20141001.Rd
Writing filename.Rd
Writing getWOEIDByCity.Rd
Writing getCityInfo.Rd
Writing getWeatherFromYahoo.Rd
Writing getWeatherByCity.Rd
Writing getWeather.Rd
Writing getColors.Rd
Writing drawBackground.Rd
Writing drawDescription.Rd
Writing drawLegend.Rd
Writing drawTemperature.Rd

文件NAMESPACE也被同时更新了,通过自动化的方式,我们又可以少维护一个文件了。运行一切正常,最后就是程序打包。

6. 程序打包

我们把用于打包的程序放到dist目录中,新建dist目录。


~ mkdir /home/conan/R/chinaWeather/dist       # 新建目录dist

6.1 程序打包

执行打包函数build(),存在于dist目录。


> build("/home/conan/R/chinaWeather",path="dist")
'/usr/lib/R/bin/R' --vanilla CMD build '/home/conan/R/chinaWeather' --no-manual --no-resave-data

* checking for file ‘/home/conan/R/chinaWeather/DESCRIPTION’ ... OK
* preparing ‘chinaWeather’:
* checking DESCRIPTION meta-information ... OK
* checking for LF line-endings in source and make files
* checking for empty or unneeded directories
* looking to see if a ‘data/datalist’ file should be added
* building ‘chinaWeather_0.1.tar.gz’

[1] "dist/chinaWeather_0.1.tar.gz"

在本地安装chinaWeather包。


~ R CMD INSTALL dist/chinaWeather_0.1.tar.gz
* installing to library ‘/home/conan/R/x86_64-pc-linux-gnu-library/3.1’
* installing *source* package ‘chinaWeather’ ...
** R
** data
*** moving datasets to lazyload DB
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (chinaWeather)

加载chinaWeather包,下载当天的天气数据,并可视化输出,如图5-20所示。


> library(chinaWeather)
> data<-getWeather(lang='zh')
[1] "2151330 ==> 8 19 28 32 NA 1023.5 0"
[1] "2151849 ==> 17 25 34 51 9.99 1015.92 0"
[1] "2159908 ==> 9 19 30 35 9.99 1015.92 0"
[1] "20070171 ==> 16 26 28 60 NA 1021.7 0"
[1] "2141166 ==> 0 14 34 22 9.99 1015.92 0"
[1] "2137321 ==> 2 16 30 27 9.99 1015.92 2"
[1] "2148332 ==> 6 18 28 35 9.99 1015.92 0"
[1] "2149760 ==> 3 15 30 31 9.99 1015.92 0"
[1] "2171287 ==> 9 22 34 27 9.99 1015.92 2"
[1] "26198317 ==> 9 18 34 55 9.99 1015.92 2"
[1] "2145605 ==> 6 21 32 39 NA 812.73 0"
[1] "2138941 ==> 3 19 32 34 NA 745.01 0"
[1] "2157249 ==> 12 26 32 44 NA 1022 0"
[1] "2150551 ==> 8 21 32 29 16 1022.7 0"
[1] "2172736 ==> 13 24 20 64 1.5 1015.92 0"
[1] "2168327 ==> 9 21 32 44 15 1022.3 0"
[1] "2154547 ==> 6 20 34 26 9.99 1015.92 2"
[1] "2127866 ==> 15 26 34 42 9.99 1015.92 2"
[1] "2163866 ==> 17 28 28 55 4.01 1019.8 0"
[1] "26198213 ==> 17 28 34 33 9.99 1015.92 0"
[1] "2137081 ==> 14 25 30 54 9.99 1015.92 2"
[1] "2158433 ==> 18 28 30 37 9.99 1015.92 2"
[1] "2146703 ==> 11 22 28 53 9.99 1015.92 2"
[1] "2160693 ==> 8 20 30 49 9.99 1015.92 2"
[1] "2166473 ==> 19 29 30 74 9 982.05 2"
[1] "26198235 ==> -1 16 32 20 NA 643.41 0"
[1] "2132574 ==> 16 25 34 39 9.99 1015.92 0"
[1] "26198151 ==> 19 28 30 40 NA 1018.4 0"
[1] "2161838 ==> 20 31 34 31 9.99 982.05 0"
[1] "2139963 ==> 18 27 34 42 9.99 982.05 2"
[1] "2306179 ==> 23 27 28 51 9.99 982.05 0"
[1] "2162779 ==> 23 28 30 66 9.99 982.05 2"
[1] "24865698 ==> 23 29 30 38 9.99 982.05 0"
[1] "20070017 ==> 25 29 34 48 9.99 982.05 2"

> drawTemperature(data,date=Sys.Date())

w10

6.2 check检查

打包过程一切正常,接下就是check()函数检查。 从check()函数的输出来看,顺利地通过了检查,但其实程序调试的过程中遇到了N多的问题,是一点一点花时间解决的。


> check("/home/conan/R/chinaWeather")            # 执行check检查
Updating chinaWeather documentation
Loading chinaWeather
'/usr/lib/R/bin/R' --vanilla CMD build '/home/conan/R/chinaWeather' --no-manual --no-resave-data

* checking for file ‘/home/conan/R/chinaWeather/DESCRIPTION’ ... OK
* preparing ‘chinaWeather’:
* checking DESCRIPTION meta-information ... OK
* checking for LF line-endings in source and make files
* checking for empty or unneeded directories
* looking to see if a ‘data/datalist’ file should be added
* building ‘chinaWeather_0.1.tar.gz’

'/usr/lib/R/bin/R' --vanilla CMD check '/tmp/Rtmp3YI3Ar/chinaWeather_0.1.tar.gz' --timings

* using log directory ‘/tmp/Rtmp3YI3Ar/chinaWeather.Rcheck’
* using R version 3.1.1 (2014-07-10)
* using platform: x86_64-pc-linux-gnu (64-bit)
* using session charset: UTF-8
* checking for file ‘chinaWeather/DESCRIPTION’ ... OK
* checking extension type ... Package
* this is package ‘chinaWeather’ version ‘0.1’
* checking package namespace information ... OK
* checking package dependencies ... OK
* checking if this is a source package ... OK
* checking if there is a namespace ... OK
* checking for executable files ... OK
* checking for hidden files and directories ... OK
* checking for portable file names ... OK
* checking for sufficient/correct file permissions ... OK
* checking whether package ‘chinaWeather’ can be installed ... OK
* checking installed package size ... OK
* checking package directory ... OK
* checking DESCRIPTION meta-information ... OK
* checking top-level files ... OK
* checking for left-over files ... OK
* checking index information ... OK
* checking package subdirectories ... OK
* checking R files for non-ASCII characters ... OK
* checking R files for syntax errors ... OK
* checking whether the package can be loaded ... OK
* checking whether the package can be loaded with stated dependencies ... OK
* checking whether the package can be unloaded cleanly ... OK
* checking whether the namespace can be loaded with stated dependencies ... OK
* checking whether the namespace can be unloaded cleanly ... OK
* checking loading without being on the library search path ... OK
* checking dependencies in R code ... OK
* checking S3 generic/method consistency ... OK
* checking replacement functions ... OK
* checking foreign function calls ... OK
* checking R code for possible problems ... OK
* checking Rd files ... OK
* checking Rd metadata ... OK
* checking Rd line widths ... OK
* checking Rd cross-references ... OK
* checking for missing documentation entries ... OK
* checking for code/documentation mismatches ... OK
* checking Rd \usage sections ... OK
* checking Rd contents ... OK
* checking for unstated dependencies in examples ... OK
* checking contents of ‘data’ directory ... OK
* checking data for non-ASCII characters ... OK
* checking data for ASCII and uncompressed saves ... OK
* checking examples ... OK
* checking PDF version of manual ... OK

6.3 Github上传

最后,把项目代码上传到Github中,在Github中开源发布。


~ git add .
~ git commit -m 'app
~ git push origin app
To https://github.com/bsspirit/chinaWeatherDemo.git
 * [new branch]      app -> app

项目的访问地址为 https://github.com/bsspirit/chinaWeatherDemo/tree/app,感兴趣的用户可以自行查看源代码。

6.4 从Github安装chinaWeatherDemo项目

我们把代码上传到github的同时,就完成了在Github上发布项目,用户可以通过devtools包从Github安装项目。


> library(devtools)       # 加载devtools包
> install_github("bsspirit/chinaWeatherDemo",ref="app") # 安装项目,配置app分支
Downloading github repo bsspirit/chinaWeatherDemo@app
Installing chinaWeather
'/usr/lib/R/bin/R' --vanilla CMD INSTALL '/tmp/RtmpTkR2Sd/devtools8435b61dfe5/bsspirit-chinaWeatherDemo-54e36d4'  \
  --library='/home/conan/R/x86_64-pc-linux-gnu-library/3.1' --install-tests

* installing *source* package ‘chinaWeather’ ...
** R
** data
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (chinaWeather)
Reloading installed chinaWeather

到此为止,整个项目关于R语言的程序开发部分,就全都完成了。接下来就是PHP的部分了,下一篇文章中将继续介绍。

转载请注明出处:
http://blog.fens.me/r-package-chinaweather/

打赏作者

Hexo在github上构建免费的Web应用

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/hexo-blog-github/

hexo-github

前言

很多次想把博客从wordpress迁移到github,为此还特意学了一下Ruby和Jekyll。但由于迁移过程过于复杂,我又没有很多时间,这个计划就被搁置了。慢慢地文章积累越来越多了,更没有时间来整理了,所以就先用着wordpress吧。

不过,了迁移博客我也有一些新的发现。hexo,一个基于Node的博客框架,同样可以实现基于github的博客,而且更轻更快,更适合Node的开发程序员。

目录

  1. Hexo介绍
  2. Hexo安装
  3. Hexo的使用
  4. 发布到项目到github
  5. 替换皮肤
  6. 配置常用插件

1. Hexo介绍

Hexo 是一个简单地、轻量地、基于Node的一个静态博客框架。通过Hexo我们可以快速创建自己的博客,仅需要几条命令就可以完成。

发布时,Hexo可以部署在自己的Node服务器上面,也可以部署github上面。对于个人用户来说,部署在github上好处颇多,不仅可以省去服务器的成本,还可以减少各种系统运维的麻烦事(系统管理、备份、网络)。所以,基于github的个人站点,正在开始流行起来….

Hexo的官方网站:http://hexo.io/ ,也是基于Github构建的网站。

2. Hexo安装

系统环境:

  • win7 64bit
  • node v0.10.5
  • npm 1.2.19

Hexo安装,要用全局安装,加-g参数。


D:\> npm install -g hexo

查看hexo的版本


D:\> hexo version
hexo: 2.5.5
os: Windows_NT 6.1.7601 win32 x64
http_parser: 1.0
node: 0.10.5
v8: 3.14.5.8
ares: 1.9.0-DEV
uv: 0.10.5
zlib: 1.2.3
modules: 11
openssl: 1.0.1e

安装好后,我们就可以使用Hexo创建项目了。


D:\workspace\javascript> hexo init nodejs-hexo 
[info] Creating file: source/_posts/hello-world.md
[info] Creating file: package.json
[info] Creating file: .gitignore
[info] Copying file: _config.yml
[info] Copying file: scaffolds/draft.md
[info] Copying file: scaffolds/page.md
[info] Copying file: scaffolds/photo.md
[info] Copying file: scaffolds/post.md
[info] Creating folder: source/_drafts
[info] Creating folder: scripts
[info] Copying theme data...
[info] Initialization has been done. Start blogging with Hexo!

我们看到当前在目录下,出现了一个文件夹,包括初始化的文件。

进入目录,并启动Hexo服务器。


# 进入目录
D:\workspace\javascript>cd nodejs-hexo

# 启动hexo服务器
D:\workspace\nodejs-hexo>hexo server
[info] Hexo is running at http://localhost:4000/. Press Ctrl+C to stop.

这时端口4000被打开了,我们能过浏览器打开地址,http://localhost:4000/ 。

hexo-web

出现了默认的网页界面,是不是很容易呢!!

3. Hexo的使用

接下来,我们要对Hexo做更全面的了解,才能做出个性化一的博客。

3.1 目录和文件

先来看一下,默认生成了哪些东西。

hexo-folder

  • scaffolds 脚手架,也就是一个工具模板
  • scripts 写文件的js,扩展hexo的功能
  • source 存放博客正文内容
  • source/_drafts 草稿箱
  • source/_posts 文件箱
  • themes 存放皮肤的目录
  • themes/landscape 默认的皮肤
  • _config.yml 全局的配置文件
  • db.json 静态常量

在这里,我们每次用到的就是_posts目录里的文件,而_config.yml文件和themes目录是第一次配置好就行了。

_posts目录:Hexo是一个静态博客框架,因此没有数据库。文章内容都是以文本文件方式进行存储的,直接存储在_posts的目录。Hexo天生集成了markdown,我们可以直接使用markdown语法格式写博客,例如:hello-world.md。新增加一篇文章,就在_posts目录,新建一个xxx.md的文件。

themes目录:是存放皮肤的,包括一套Javascript+CSS样式和基于EJS的模板设置。通过在themes目录下,新建一个子目录,就可以创建一套新的皮肤,当然我们也可以直接在landscape上面修改。

3.2 全局配置

_config.yml是全局的配置文件:很多的网站配置都在这个文件中定义。

  • 站点信息: 定义标题,作者,语言
  • URL: URL访问路径
  • 文件目录: 正文的存储目录
  • 写博客配置:文章标题,文章类型,外部链接等
  • 目录和标签:默认分类,分类图,标签图
  • 归档设置:归档的类型
  • 服务器设置:IP,访问端口,日志输出
  • 时间和日期格式: 时间显示格式,日期显示格式
  • 分页设置:每页显示数量
  • 评论:外挂的Disqus评论系统
  • 插件和皮肤:换皮肤,安装插件
  • Markdown语言:markdown的标准
  • CSS的stylus格式:是否允许压缩
  • 部署配置:github发布

查看文件:_config.yml


# Hexo Configuration
## Docs: http://hexo.io/docs/configuration.html
## Source: https://github.com/tommy351/hexo/

# 站点信息
title: Hexo博客
subtitle: 新的开始
description: blog.fens.me
author: bsspirit
email: bsspirit@gmail.com
language: zh-CN

# URL
## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'
url: http://blog.fens.me
root: /
permalink: :year/:month/:day/:title/
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code

# 文件目录
source_dir: source
public_dir: public

# 写博客配置
new_post_name: :title.md # File name of new posts
default_layout: post
auto_spacing: false # Add spaces between asian characters and western characters
titlecase: false # Transform title into titlecase
external_link: true # Open external links in new tab
max_open_file: 100
multi_thread: true
filename_case: 0
render_drafts: false
post_asset_folder: false
highlight:
  enable: true
  line_number: true
  tab_replace:

# 目录和标签
default_category: uncategorized
category_map:
tag_map:

# 归档设置
## 2: Enable pagination
## 1: Disable pagination
## 0: Fully Disable
archive: 2
category: 2
tag: 2

# 服务器设置
## Hexo uses Connect as a server
## You can customize the logger format as defined in
## http://www.senchalabs.org/connect/logger.html
port: 4000
server_ip: 0.0.0.0
logger: false
logger_format:

# 时间和日期格式
## Hexo uses Moment.js to parse and display date
## You can customize the date format as defined in
## http://momentjs.com/docs/#/displaying/format/
date_format: MMM D YYYY
time_format: H:mm:ss

# 分页设置
## Set per_page to 0 to disable pagination
per_page: 10
pagination_dir: page

# 评论
disqus_shortname:

# 插件和皮肤
## Plugins: https://github.com/tommy351/hexo/wiki/Plugins
## Themes: https://github.com/tommy351/hexo/wiki/Themes
theme: landscape
exclude_generator:

# Markdown语法
## https://github.com/chjj/marked
markdown:
  gfm: true
  pedantic: false
  sanitize: false
  tables: true
  breaks: true
  smartLists: true
  smartypants: true

# CSS的stylus格式
stylus:
  compress: false

# 部署配置
## Docs: http://hexo.io/docs/deployment.html
deploy:
  type:

3.3 命令行使用

查看命令行帮助


D:\> hexo help
Usage: hexo 

Commands:
  help      Get help on a command
  init      Create a new Hexo folder
  migrate   Migrate your site from other system to Hexo
  version   Display version information

Global Options:
  --config   Specify config file instead of using _config.yml
  --debug    Display all verbose messages in the terminal
  --safe     Disable all plugins and scripts
  --silent   Hide output on console

For more help, you can use `hexo help [command]` for the detailed information
or you can check the docs: http://hexo.io/docs/

命令行解释:

  • help 查看帮助信息
  • init 创建一个hexo项目
  • migrate 从其他系统向hexo迁移
  • version 查看hexo的版本
  • –config参数,指定配置文件,代替默认的_config.yml
  • –debug参数,调试模式,输出所有日志信息
  • –safe参数,安全模式,禁用所有的插件和脚本
  • –silent参数,无日志输出模式

3.4 创建新文章

接下来,我们开始新博客了,创建第一博客文章。Hexo建议通过命令行操作,当然你也可以直接在_posts目录下创建文件。

通过命令创建新文章


D:\workspace\javascript\nodejs-hexo>hexo new 新的开始
[info] File created at D:\workspace\javascript\nodejs-hexo\source\_posts\新的开始.md

在_posts目录下,就会生成文件:”新的开始.md”。

hexo-post

然后,我们编辑文件:”新的开始.md”,以markdown语法写文章,然后保存。


title: 新的开始
date: 2014-05-07 18:44:12
tags:
- 开始
- 我
- 日记
categories: 日志
---

这是**新的开始**,我用hexo创建了第一篇文章。

通过下面的命令,就可以创建新文章
```{bash}
D:\workspace\javascript\nodejs-hexo>hexo new 新的开始
[info] File created at D:\workspace\javascript\nodejs-hexo\source\_posts\新的开始.md
```

感觉非常好。

在命令行,启动服务器。


D:\workspace\javascript\nodejs-hexo>hexo server
[info] Hexo is running at http://localhost:4000/. Press Ctrl+C to stop.

通过浏览器打开, http://localhost:4000/ ,就出现了我们新写的文章。

hexo-index

同时,网页的右侧还会出现Categories(目录),Tags(标签),Tag Cloud(标签云)的显示。

3.5 文章的语法

我们在写文章时,有一些语法的要求。

语法包括3部分:

  • 基本信息:标题,发布日期,分类目录,标签,类型,固定发布链接
  • 正文:markdown语法和Swig语法(掌握一个就行)
  • 特殊标记:引用,链接,图片,代码块,iframe,youtube视频

3.5.1 基本信息

必须在文件的顶部,—的行之前的部分。如:


title: 新的开始
date: 2014-05-07 18:44:12
updated	: 2014-05-10 18:44:12
permalink: abc
tags:
- 开始
- 我
- 日记
categories:
- 日志
- 第一天

---

我们可以对刚才发的文章,做上面的修改,再看效果。

3.5.2 正文

hexo的正文要求使用markdown的语法,这里就不在多说,请自行查看markdwon的文档。

3.5.3 特殊标记

hexo对于一些有特殊标记 文字块,做了特殊的定义。

引用


# Swig语法
{% blockquote Seth Godin http://sethgodin.typepad.com/seths_blog/2009/07/welcome-to-island-marketing.html Welcome to Island Marketing %}
Every interaction is both precious and an opportunity to delight.
{% endblockquote %}

# Markdown语法
> Every interaction is both precious and an opportunity to delight.

代码块


# Swig语法
{% codeblock .compact http://underscorejs.org/#compact Underscore.js %}
.compact([0, 1, false, 2, ‘’, 3]);
=> [1, 2, 3]
{% endcodeblock %}

# Markdown语法
```{bash}
.compact([0, 1, false, 2, ‘’, 3]);
=> [1, 2, 3]
```

链接


{% link 粉丝日志 http://blog.fens.me true 粉丝日志 %}

# Markdown语法
[粉丝日志](http://blog.fens.me)

图片,对于本地图片,需要在source目录下面新建一个目录images,然后把图片放到目录中。


# Swig语法
{% img /images/fens.me.png 400 600 这是一张图片 %}

# Markdown语法
![这是一张图片](/images/fens.me.png)

在浏览器中看到效果。

hexo-content

我们发现Swig的语法比markdown语法有更多的配置项,可以让页面更丰富,下面显示完整的基于Swig代码。


title: 新的开始
date: 2014-05-07 18:44:12
permalink: abc
tags:
- 开始
- 我
- 日记
categories:
- 日志
- 第一天

---

这是**新的开始**,我用hexo创建了第一篇文章。

通过下面的命令,就可以创建新文章
```{bash}
D:\workspace\javascript\nodejs-hexo>hexo new 新的开始
[info] File created at D:\workspace\javascript\nodejs-hexo\source\_posts\新的开始.md
```

感觉非常好。


## 引用
{% blockquote Seth Godin http://sethgodin.typepad.com/seths_blog/2009/07/welcome-to-island-marketing.html Welcome to Island Marketing %}
Every interaction is both precious and an opportunity to delight.
{% endblockquote %}

## 代码块
{% codeblock .compact http://underscorejs.org/#compact Underscore.js %}
.compact([0, 1, false, 2, ‘’, 3]);
=> [1, 2, 3]
{% endcodeblock %}

## 链接
{% link 粉丝日志 http://blog.fens.me true 粉丝日志 %}

## 图片
{% img /images/fens.me.png 400 600 这是一张图片 %}

4. 发布到项目到github

4.1 静态化处理

写完了文章,我们就可以发布了。要说明的一点是hexo的静态博客框架,那什么是静态博客呢?静态博客,是只包含html, javascript, css文件的网站,没有动态的脚本。虽然我们是用Node进行的开发,但博客的发布后就与Node无关了。在发布之前,我们要通过一条命令,把所有的文章都做静态化处理,就是生成对应的html, javascript, css,使得所有的文章都是由静态文件组成的。

静态化命令


D:\workspace\javascript\nodejs-hexo>hexo generate
[info] Files loaded in 0.895s
[create] Public: js\script.js
[create] Public: css\fonts\fontawesome-webfont.svg
[create] Public: css\fonts\FontAwesome.otf
[create] Public: css\fonts\fontawesome-webfont.ttf
[create] Public: css\fonts\fontawesome-webfont.eot
[create] Public: css\fonts\fontawesome-webfont.woff
[create] Public: fancybox\blank.gif
[create] Public: fancybox\fancybox_loading@2x.gif
[create] Public: fancybox\fancybox_overlay.png
[create] Public: css\images\banner.jpg
[create] Public: fancybox\fancybox_sprite.png
[create] Public: fancybox\jquery.fancybox.css
[create] Public: fancybox\fancybox_loading.gif
[create] Public: fancybox\fancybox_sprite@2x.png
[create] Public: fancybox\jquery.fancybox.js
[create] Public: fancybox\jquery.fancybox.pack.js
[create] Public: fancybox\helpers\jquery.fancybox-buttons.js
[create] Public: fancybox\helpers\fancybox_buttons.png
[create] Public: fancybox\helpers\jquery.fancybox-buttons.css
[create] Public: fancybox\helpers\jquery.fancybox-media.js
[create] Public: fancybox\helpers\jquery.fancybox-thumbs.css
[create] Public: fancybox\helpers\jquery.fancybox-thumbs.js
[create] Public: archives\index.html
[create] Public: images\fens.me.png
[create] Public: archives\2014\index.html
[create] Public: archives\2014\05\index.html
[create] Public: css\style.css
[create] Public: index.html
[create] Public: categories\日志\index.html
[create] Public: categories\日志\第一天\index.html
[create] Public: 2014\05\07\abc\index.html
[create] Public: 2014\05\07\hello-world\index.html
[create] Public: tags\开始\index.html
[create] Public: tags\我\index.html
[create] Public: tags\日记\index.html
[info] 35 files generated in 0.711s

在本地目录下,会生成一个public的目录,里面包括了所有静态化的文件。

4.2 发布到github

接下来,我们把这个博客发布到github。

在github中创建一个项目nodejs-hexo,项目地址:https://github.com/bsspirit/nodejs-hexo

编辑全局配置文件:_config.yml,找到deploy的部分,设置github的项目地址。


deploy:
  type: github
  repo: git@github.com:bsspirit/nodejs-hexo.git

然后,通过命令进行部署。


D:\workspace\javascript\nodejs-hexo>hexo deploy
[info] Start deploying: github
[info] Setting up GitHub deployment...
Initialized empty Git repository in D:/workspace/javascript/nodejs-hexo/.deploy/.git/
[master (root-commit) 43873d3] First commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 placeholder
[info] Clearing .deploy folder...
[info] Copying files from public folder...

// 省略部分输出

Branch gh-pages set up to track remote branch gh-pages from github.
To git@github.com:bsspirit/nodejs-hexo.git
 * [new branch]      gh-pages -> gh-pages
[info] Deploy done: github

这个静态的web网站就被部署到了github,检查一下分支是gh-pages。gh-pages是github为了web项目特别设置的分支。

hexo-github

然后,点击”Settings”,找到GitHub Pages,提示“Your site is published at http://bsspirit.github.io/nodejs-hexo”,打开网页 http://bsspirit.github.io/nodejs-hexo,就是我们刚刚发布的站点。

hexo-github-page

4.3 设置域名

看起来css和js的加载路径不太对,不过没有关系。接下来,我们配置好域名,这个路径就会正确的。比如,我有一个域名是 52u.me,为了中国DNS解析,我先把域名绑定在Dnspod管理,再做跳转。

域名有两种配置方式:

  • 主域名绑定:直接绑定主域名52u.me
  • 子域名绑定:绑定子域名blog.52u.me
    • 4.3.1 主域名绑定

      在dnspod控制台,设置主机记录@,类型A,到IP 192.30.252.153。

      dnspod-1

      大概等几分钟会生效。判断生效,对域名执行ping或者dig命令。

      
      D:\workspace\javascript\nodejs-hexo>ping 52u.me
      
      正在 Ping 52u.me [192.30.252.153] 具有 32 字节的数据:
      来自 192.30.252.153 的回复: 字节=32 时间=321ms TTL=48
      来自 192.30.252.153 的回复: 字节=32 时间=325ms TTL=48
      来自 192.30.252.153 的回复: 字节=32 时间=329ms TTL=48
      来自 192.30.252.153 的回复: 字节=32 时间=326ms TTL=48
      
      192.30.252.153 的 Ping 统计信息:
          数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
      往返行程的估计时间(以毫秒为单位):
          最短 = 321ms,最长 = 329ms,平均 = 325ms
      

      在github项目中,新建一个文件CNAME,文件中写出你要绑定的域名52u.me。通过浏览器,访问http://52u.me,就打开了我们建好的博客站点。

      52u.me

      4.3.2 子域名绑定

      有时候,我们的主域名正在使用着,需要先新建一个博客绑定到子域名,比如: blog.52u.me。

      dnspod-2

      在dnspod控制台,我们要做3步设置。

      • 设置主机记录github,类型A,到IP 199.27.76.133
      • 设置主机记录bsspirit.github.io,类型CNAME,到github.52u.me.
      • 设置主机记录blog,类型CNAME,到 bsspirit.github.io

      记得我们还要修改文件CNAME,改为blog.52u.me。通过浏览器,访问http://blog.52u.me,就可以打开了我们的博客站点了,而这次用的是二级域名。

      由于每次执行deploy的时候,gh-pages分支所有的文件都会被覆盖,所以我们最好在source目录下创建这个CNAME文件,这样每次部署就不用动手创建了。

      5. 替换皮肤

      博客系统流行的原因,是因为他的个人性,而皮肤正式个性化的一种体现。

      利用hexo替换皮肤,还是比较简单的,3步完成。

      5.1 找到一个皮肤或者自己开发一个皮肤

      打开hexo的皮肤列表页面,你可以找到很多的皮肤,网页地址: https://github.com/tommy351/hexo/wiki/Themes。

      5.2. 放到themes目录下

      比如,我觉得pacman(https://github.com/A-limon/pacman)这个皮肤还不错,我就可以下载皮肤到themes目录下面。

      通过git命令下载皮肤

      
      git clone https://github.com/A-limon/pacman.git themes/pacman
      

      5.3. 在_config.yml指定皮肤

      编辑文件_config.yml,找到theme一行,改成 theme: pacman

      本地启动hexo服务器,打开浏览器 http://localhost:4000

      hexo-theme

      新皮肤的效果还不错吧,然后静态化处理,再发布到github,就完成了站点的改版。

      6. 配置常用插件

      6.1 Disqus评论系统

      首先登陆http://disqus.com/ 网站,申请一个新网站的shortname,配置到_config.yml文件里,disqus_shortname: blog52ume

      disqus

      然后,你会得到一段js代码,把他复制文件 themes/pacman/layout/_partial/comment.ejs 。继续修改themes/pacman/layout/layout.ejs文件,增加对comment.ejs的引用。具体修改请详见代码。

      disqus-comment

      这样,评论系统就增加好了!!

      6.2 RSS订阅

      这个功能非常简单,因为已经有人写好了插件,我们只要安装插件就行了。

      
      D:\workspace\javascript\nodejs-hexo>npm install hexo-generator-feed
      npm WARN package.json hexo-site@2.5.5 No readme data!
      npm http GET https://registry.npmjs.org/hexo-generator-feed
      npm http 304 https://registry.npmjs.org/hexo-generator-feed
      npm http GET https://registry.npmjs.org/ejs/0.8.5
      npm http GET https://registry.npmjs.org/lodash/2.4.1
      npm http 304 https://registry.npmjs.org/ejs/0.8.5
      npm http 200 https://registry.npmjs.org/lodash/2.4.1
      npm http GET https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz
      npm http 200 https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz
      hexo-generator-feed@0.1.0 node_modules\hexo-generator-feed
      ├── ejs@0.8.5
      └── lodash@2.4.1
      

      启动服务器,用浏览器打开 http://localhost:4000/atom.xml, 就可以看到RSS已经生效了。

      6.3 Sitemap站长地图

      同样是一条命令,就可以完成。

      
      D:\workspace\javascript\nodejs-hexo>npm install hexo-generator-sitemap
      npm WARN package.json hexo-site@2.5.5 No readme data!
      npm http GET https://registry.npmjs.org/hexo-generator-sitemap
      npm http 304 https://registry.npmjs.org/hexo-generator-sitemap
      npm http GET https://registry.npmjs.org/ejs/0.8.5
      npm http GET https://registry.npmjs.org/lodash/2.4.1
      npm http 304 https://registry.npmjs.org/lodash/2.4.1
      npm http 304 https://registry.npmjs.org/ejs/0.8.5
      hexo-generator-sitemap@0.1.1 node_modules\hexo-generator-sitemap
      ├── ejs@0.8.5
      └── lodash@2.4.1
      

      启动服务器,用浏览器打开 http://localhost:4000/sitemap.xml, 就可以看到sitemap已经生效了。

      6.4 mathjax数学公式

      有时候,我们还需要一些高级功能,比如在网页上显示数学公式。

      新建一个文件themes/pacman/layout/_partial/mathjax.ejs,找到mathjax的调用代码复制到文件。

      
      <!-- mathjax config similar to math.stackexchange -->
      
      <script type="text/x-mathjax-config">
        MathJax.Hub.Config({
          tex2jax: {
            inlineMath: [ ['$','$'], ["\\(","\\)"] ],
            processEscapes: true
          }
        });
      </script>
      
      <script type="text/x-mathjax-config">
          MathJax.Hub.Config({
            tex2jax: {
              skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
            }
          });
      </script>
      
      <script type="text/x-mathjax-config">
          MathJax.Hub.Queue(function() {
              var all = MathJax.Hub.getAllJax(), i;
              for(i=0; i < all.length; i += 1) {
                  all[i].SourceElement().parentNode.className += ' has-jax';
              }
          });
      </script>
      
      <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
      </script>
      

      在themes/pacman/layout/_partial/after_footer.ejs 的最后一行,增加对mathjax的引用,详细内容请查看源代码。

      我们修改文章:source/_posts/新的开始.md

      增加公式:

      
      ## 公式
      $$J\_\alpha(x)=\sum _{m=0}^\infty \frac{(-1)^ m}{m! \, \Gamma (m + \alpha + 1)}{\left({\frac{x}{2}}\right)}^{2 m + \alpha }$$
      

      启动服务器,查看效果:

      math

      当然,除了这些还有很多需要的功能,像Google分析,百度统计,微薄转发等,大家可以自己找找,也可以自己开发一些插件!

      最后,本文的中代码已经上传的github,https://github.com/bsspirit/nodejs-hexo。 其中master分支是项目源代码,gh-pages分支是发布的站点。

      Hexo框架确实如同它介绍中的话: “A fast, simple & powerful blog framework, powered by Node.js.”,Noder还等什么,赶紧搭建一个博客吧!!

      转载请注明出处:
      http://blog.fens.me/hexo-bootstarp-github/

      打赏作者

Passport现实社交网络OAuth登陆

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/nodejs-oauth-passport/

nodejs-passport-oauth

前言

随着社交网络的发展,开发一个应用门槛越来越低。从一个完整的应用系统,到一个部署在社交网络平台的APP;从数据库–》应用层–》展示层,变成只需要开发展示层。

很多的社交应用,甚至都放弃了用户注册!仅靠大型社交网站的登陆授权,就可以赚到100W以上的用户量。。。

减少用户管理代码开发及维护,更专注于应用本身,个人开发者已经崛起!!

目录

  1. Passport介绍
  2. OAuth介绍
  3. 登陆Github
  4. 登陆LinkedIn

1. Passport介绍

Passport项目,主要是为了解决登陆认证的问题。

Web应用一般有2种登陆认证的形式:

  • 用户名和密码认证登陆
  • OAuth认证登陆

在上一篇文章中,我们介绍了Passport的项目,通过用户名和密码认证登陆。Express结合Passport实现登陆认证

本文将介绍,通过Passport实现OAuth登陆认证。

2. OAuth介绍

OAuth协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAuth的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAuth是安全的。

  • 简单:不管是OAUTH服务提供者还是应用开发者,都很易于理解与使用
  • 安全:没有涉及到用户密钥等信息,更安全更灵活
  • 开放:任何服务提供商都可以实现OAUTH,任何软件开发商都可以使用OAUTH

OAuth认证授权就三个步骤,三句话可以概括:

  • 获取未授权的Request Token
  • 获取用户授权的Request Token
  • 用授权的Request Token换取Access Token

OAuth的介绍,摘自:http://baike.baidu.com/view/3948029.htm

3. Github登陆

通过Passport实现Github登陆。我们还使用上一篇文章中的环境:Express结合Passport实现登陆认证

  • 申请开发github应用
  • Passport程序实现
  • 运行Github登陆认证

1). 申请开发github应用

github-app

2). Passport程序实现

  • 安装Passport的github扩展
  • 增加Github认证策略
  • 定义Github认证的路由配置: 登陆,回调,展示

a. 安装Passport的github扩展


D:\workspace\javascript\nodejs-passport>npm install passport-github

b. 增加Github认证策略

修改app.js


passport.use(new GithubStrategy({//对应从Github申请KEY
    clientID: "XXXX",
    clientSecret: "XXXX",
    callbackURL: "http://localhost:3000/auth/github/callback"
},function(accessToken, refreshToken, profile, done) {
    done(null, profile);
}));

c. 定义Github认证的路由配置: 登陆,回调,展示

  • /auth/github: 通过github,登陆
  • /auth/github/callback: github认证成功后,回调
  • /github: 回调验证后,转向展示示

修改app.js


app.all('/github', isLoggedIn);
app.get("/github",user.github);

app.get("/auth/github", passport.authenticate("github",{ scope : "email"}));
app.get("/auth/github/callback",
    passport.authenticate("github",{
        successRedirect: '/github',
        failureRedirect: '/'
    }));

3).运行Github登陆认证

github-auth

程序日志


D:\workspace\javascript\nodejs-passport>node app.js
Express server listening on port 3000
GET / 200 401ms - 594b
GET /stylesheets/style.css 304 9ms
GET /auth/github 302 8ms - 424b
GET /auth/github/callback?code=7cf818c4590e2aacfe90 302 4052ms - 70b
GET /github 200 4ms - 139b
GET /logout 302 2ms - 58b
GET / 200 3ms - 594b
GET /stylesheets/style.css 304 2ms

4. LinkedIn登陆

  • 申请开发LinkedIn应用
  • Passport程序实现
  • 运行LinkedIn登陆认证

1). 申请开发LinkedIn应用

linkedin-app

2). Passport程序实现

  • 安装Passport的LinkedIn扩展
  • 增加LinkedIn认证策略
  • 定义LinkedIn认证的路由配置: 登陆,回调,展示

a. 安装Passport的LinkedIn扩展


D:\workspace\javascript\nodejs-passport>npm install passport-linkedin

b. 增加LinkedIn认证策略

修改app.js


passport.use(new LinkedinStrategy({
    consumerKey: "XXXX",
    consumerSecret: "XXXX",
    callbackURL: "http://localhost:3000/auth/linkedin/callback",
    userAgent: 'localhost'
},function(accessToken, refreshToken, profile, done) {
    done(null, profile);
}));

c. 定义LinkedIn认证的路由配置: 登陆,回调,展示

  • /auth/linkedin: 通过LinkedIn,登陆
  • /auth/linkedin/callback: github认证成功后,回调
  • /linkedin: 回调验证后,转向展示示

修改app.js


app.all('/github', isLoggedIn);
app.get("/github",user.github);

app.all('/linkedin', isLoggedIn);
app.get("/linkedin",user.linkedin);
app.get("/auth/linkedin", passport.authenticate("linkedin",{}));
app.get("/auth/linkedin/callback",
    passport.authenticate("linkedin",{
        successRedirect: '/linkedin',
        failureRedirect: '/'
    }));

3).运行LinkedIn登陆认证

linkedin-auth

程序日志


D:\workspace\javascript\nodejs-passport>node app.js
Express server listening on port 3000
GET / 200 399ms - 638b
GET /stylesheets/style.css 304 4ms
GET /auth/Linkedin 302 3092ms - 256b
GET /auth/linkedin/callback?oauth_token=75--8f032180-afae-489b-bc3c-3326d80bea6f&oauth_verifier=36091 302 3049ms - 74b
GET /linkedin 200 5ms - 76b
GET /logout 302 1ms - 58b
GET / 200 19ms - 638b
GET /stylesheets/style.css 304 2ms

5. 完整的应用

项目代码我已上传到了github, 项目地址:https://github.com/bsspirit/nodejs-passport

下载及安装


git clone https://github.com/bsspirit/nodejs-passport
npm install

我们非常方便地,实现了Github和LinkedIn登陆认证,是否已经体会到Passport的强大了!把权限这种基础功能,进行合理的封装,是会帮我们节省大量的工作量的。

转载请注明出处:
http://blog.fens.me/nodejs-oauth-passport/

打赏作者

Jekyll在github上构建免费的Web应用

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/jekyll-bootstarp-github/

jekyll-github

前言

程序员会写程序是基本技能,程序员会写文档是更高的能力。用简单的图形表达架构,用流畅语言描述业务,用专业的文笔写成报告,看似简单的要求,但对于普通的程序员来说都是一种挑战。

有时候我们纠结的不是怎么组织文字,而是怎么排版,用哪种字体,居中还是靠右放置?如何能保持多人撰写文档的统一风格?

Jekyll可以帮助我们标准化文档结构,文档样式,文档过程。剩下就是提升自己的知识基础了。

目录

  1. Jekyll介绍
  2. 安装Ruby
  3. 安装Jekyll
  4. 用Jekyll构建基于bootstrap模板
  5. 发布到Github

1. Jekyll介绍

Jekyll是一个静态站点生成器,它会根据网页源码生成静态文件。它提供了模板、变量、插件等功能,可以用来生成整个网站。

Jekyll生成的站点,可以直接发布到github上面,这样我们就有了一个免费的,无限流量的,有人维护的属于我们的自己的web网站。Jekyll是基于Ruby的程序,可以通过gem来下载安装。

Jekyll官方文档:http://jekyllrb.com/

2. 安装Ruby

我的系统环境

  • win7 64bit

下载Ruby 2.0.0-p247 (x64): http://rubyinstaller.org/downloads/

安装Ruby,再安装RubyGems


~ D:\workspace\ruby>ruby --version
ruby 2.0.0p247 (2013-06-27) [x64-mingw32]

~ D:\workspace\ruby>gem update --system
Updating rubygems-update
Fetching: rubygems-update-2.1.10.gem (100%)
Successfully installed rubygems-update-2.1.10
Parsing documentation for rubygems-update-2.1.10
Installing ri documentation for rubygems-update-2.1.10
Installing darkfish documentation for rubygems-update-2.1.10
Installing RubyGems 2.1.10
RubyGems 2.1.10 installed
Parsing documentation for rubygems-2.1.10
Installing ri documentation for rubygems-2.1.10

3. 安装Jekyll

安装jekll


~ D:\workspace\ruby>gem install jekyll
ERROR:  Could not find a valid gem 'jekyll' (>= 0), here is why:
          Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=SSLv3 read server ce
rtificate B: certificate verify failed (https://rubygems.global.ssl.fastly.net/quick/Marshal.4.8/jekyll-1.3.0.gemspec.rz
)
ERROR:  Possible alternatives: jekyll

问题1:下载认证文件


~ D:\workspace\ruby>curl http://curl.haxx.se/ca/cacert.pem -o cacert.pem
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  223k  100  223k    0     0  82478      0  0:00:02  0:00:02 --:--:-- 94724

# 移动到Ruby安装目录
~ D:\workspace\ruby>mv cacert.pem D:\toolkit\Ruby200\bin

设置环境变量

ruby-ssl

新打开一个命令行,再安装jekll


~ D:\workspace\ruby>gem install jekyll
ERROR:  Error installing jekyll:
        The 'fast-stemmer' native gem requires installed build tools.

Please update your PATH to include build tools or download the DevKit
from 'http://rubyinstaller.org/downloads' and follow the instructions
at 'http://github.com/oneclick/rubyinstaller/wiki/Development-Kit'

问题2:安装Devkit,下载DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe:http://rubyinstaller.org/downloads/

解压到目录:D:\toolkit\devkit

运行msys.bat,打开ruby命令行,再安装jekll


Administrator@PC201304202140 ~
$ gem install jekyll
Building native extensions.  This could take a while...
Successfully installed fast-stemmer-1.0.2
Fetching: classifier-1.3.3.gem (100%)
Successfully installed classifier-1.3.3
Fetching: rb-fsevent-0.9.3.gem (100%)
Successfully installed rb-fsevent-0.9.3
Fetching: ffi-1.9.3-x64-mingw32.gem (100%)
Successfully installed ffi-1.9.3-x64-mingw32
Fetching: rb-inotify-0.9.2.gem (100%)
Successfully installed rb-inotify-0.9.2
Fetching: rb-kqueue-0.2.0.gem (100%)
Successfully installed rb-kqueue-0.2.0
Fetching: listen-1.3.1.gem (100%)
Successfully installed listen-1.3.1
Fetching: syntax-1.0.0.gem (100%)
Successfully installed syntax-1.0.0
Fetching: maruku-0.6.1.gem (100%)
Successfully installed maruku-0.6.1
Fetching: yajl-ruby-1.1.0.gem (100%)
Building native extensions.  This could take a while...
Successfully installed yajl-ruby-1.1.0
Fetching: posix-spawn-0.3.6.gem (100%)
Building native extensions.  This could take a while...
Successfully installed posix-spawn-0.3.6
Fetching: pygments.rb-0.5.4.gem (100%)
Successfully installed pygments.rb-0.5.4
Fetching: highline-1.6.20.gem (100%)
Successfully installed highline-1.6.20
Fetching: commander-4.1.5.gem (100%)
Successfully installed commander-4.1.5
Fetching: safe_yaml-0.9.7.gem (100%)
Successfully installed safe_yaml-0.9.7
Fetching: colorator-0.1.gem (100%)
Successfully installed colorator-0.1
Fetching: redcarpet-2.3.0.gem (100%)
Building native extensions.  This could take a while...
Successfully installed redcarpet-2.3.0
Fetching: jekyll-1.3.0.gem (100%)
Successfully installed jekyll-1.3.0
Parsing documentation for classifier-1.3.3
Installing ri documentation for classifier-1.3.3
Parsing documentation for colorator-0.1
Installing ri documentation for colorator-0.1
Parsing documentation for commander-4.1.5
Installing ri documentation for commander-4.1.5
Parsing documentation for fast-stemmer-1.0.2
unable to convert "\x90" from ASCII-8BIT to UTF-8 for lib/stemmer.so, skipping
Installing ri documentation for fast-stemmer-1.0.2
Parsing documentation for ffi-1.9.3-x64-mingw32
Installing ri documentation for ffi-1.9.3-x64-mingw32
Parsing documentation for highline-1.6.20
Installing ri documentation for highline-1.6.20
Parsing documentation for jekyll-1.3.0
Installing ri documentation for jekyll-1.3.0
Parsing documentation for listen-1.3.1
Installing ri documentation for listen-1.3.1
Parsing documentation for maruku-0.6.1
Couldn't find file to include 'MaRuKu.txt' from lib/maruku.rb
Installing ri documentation for maruku-0.6.1
Parsing documentation for posix-spawn-0.3.6
Installing ri documentation for posix-spawn-0.3.6
Parsing documentation for pygments.rb-0.5.4
Installing ri documentation for pygments.rb-0.5.4
Parsing documentation for rb-fsevent-0.9.3
Installing ri documentation for rb-fsevent-0.9.3
Parsing documentation for rb-inotify-0.9.2
Installing ri documentation for rb-inotify-0.9.2
Parsing documentation for rb-kqueue-0.2.0
Installing ri documentation for rb-kqueue-0.2.0
Parsing documentation for redcarpet-2.3.0
unable to convert "\x90" from ASCII-8BIT to UTF-8 for lib/redcarpet.so, skipping

Installing ri documentation for redcarpet-2.3.0
Parsing documentation for safe_yaml-0.9.7
Installing ri documentation for safe_yaml-0.9.7
Parsing documentation for syntax-1.0.0
Installing ri documentation for syntax-1.0.0
Parsing documentation for yajl-ruby-1.1.0
unable to convert "\x90" from ASCII-8BIT to UTF-8 for lib/yajl/yajl.so, skipping

Installing ri documentation for yajl-ruby-1.1.0
18 gems installed

这样就安装好了jekyll。

查看jekyll命令行帮助


$ jekyll
  NAME:
    jekyll

  DESCRIPTION:
    Jekyll is a blog-aware, static site generator in Ruby

  COMMANDS:
    build                Build your site
    default
    docs                 Launch local server with docs for Jekyll v1.3.0
    doctor               Search site and print specific deprecation warnings
    help                 Display global or [command] help documentation.
    import               Import your old blog to Jekyll
    new                  Creates a new Jekyll site scaffold in PATH
    serve                Serve your site locally

  ALIASES:
    hyde                 doctor
    server               serve

  GLOBAL OPTIONS:
    -s, --source [DIR]
        Source directory (defaults to ./)
    -d, --destination [DIR]
        Destination directory (defaults to ./_site)
    --safe
        Safe mode (defaults to false)
    -p, --plugins PLUGINS_DIR1[,PLUGINS_DIR2[,...]]
        Plugins directory (defaults to ./_plugins)
    --layouts DIR
        Layouts directory (defaults to ./_layouts)
    -h, --help
        Display help documentation
    -v, --version
        Display version information
    -t, --trace
        Display backtrace when an error occurs

4. 用Jekyll构建基于bootstrap模板

下载jekyll-bootstrap的模板项目


#从github下载模板
Administrator@PC201304202140 /d/workspace/ruby
$ git clone https://github.com/plusjade/jekyll-bootstrap.git jekyll
Cloning into 'jekyll'...
remote: Counting objects: 1898, done.
remote: Compressing objects: 100% (1061/1061), done.
remote: Total 1898 (delta 850), reused 1729 (delta 723)
Receiving objects: 100% (1898/1898), 575.45 KiB | 184 KiB/s, done.
Resolving deltas: 100% (850/850), done.

#进入项目目录
Administrator@PC201304202140 /d/workspace/ruby
$ cd jekyll/

#查看目录模板
Administrator@PC201304202140 /d/workspace/ruby/jekyll
$ ls
404.html          _config.yml  _plugins      atom.xml         pages.html
History.markdown  _drafts      _posts        categories.html  rss.xml
README.md         _includes    archive.html  changelog.md     sitemap.txt
Rakefile          _layouts     assets        index.md         tags.html

#启动服务
Administrator@PC201304202140 /d/workspace/ruby/jekyll
$ jekyll serve
Configuration file: d:/workspace/ruby/jekyll/_config.yml
            Source: d:/workspace/ruby/jekyll
       Destination: d:/workspace/ruby/jekyll/_site
      Generating... done.
    Server address: http://0.0.0.0:4000
  Server running... press ctrl-c to stop.

打开浏览器,http://localhost:4000/

jekyll-bootstrap-web

通过几条命令,基于bootstrap风格的模板就构建好了。

4. Jekyll的基本使用

  • 编写新文章(Post)
  • 编写新页面(Page)

1). 编写新文章(Create a Post)
通过命令生成文章


~ D:\workspace\ruby\jekyll>rake post title="Hello World"
Creating new post: ./_posts/2013-11-06-hello-world.md

查看文件:2013-11-06-hello-world.md

jekyll-post

编辑文件:2013-11-06-hello-world.md


~ vi ./_posts/2013-11-06-hello-world.md

---
layout: post
title: "Hello World"
description: ""
category: ""
tags: []
---
{% include JB/setup %}

## 第一页,jekyll的开始

Jekyll is a parsing engine bundled as a ruby gem used to build static websites from
dynamic components such as templates, partials, liquid code, markdown, etc. Jekyll is known as "a simple, blog aware, static site generator".

### 博客文章:[用Jekyll构建基于bootstrap系统](http://blog.fens.me/jekyll-bootstarp-doc/)

程序员会写程序是基本技能,程序员会写文档是更高的能力。用简单的图形表达架构,用流畅语言描述业务,用专业的文笔写成报告,看似简单的要求,但对于普通的程序员来说都是一种挑战。

有时候我们纠结的不是怎么组织文字,而是怎么排版,用哪种字体,居中还是靠右放置?如何能保持多人撰写文档的统一风格?

Jekyll可以帮助我们标准化文档结构,文档样式,文档过程。剩下就是提升自己的知识基础了。

保存后,启动服务器。


Administrator@PC201304202140 /d/workspace/ruby/jekyll
$ jekyll serve
Configuration file: d:/workspace/ruby/jekyll/_config.yml
            Source: d:/workspace/ruby/jekyll
       Destination: d:/workspace/ruby/jekyll/_site
      Generating... Error reading file d:/workspace/ruby/jekyll/_posts/2013-11-0
6-hello-world.md: invalid byte sequence in GBK
error: invalid byte sequence in GBK. Use --trace to view backtrace

发现中文的GBK编码报错。

找到jekyll安装目录,修改convertible.rb文件,第38行


~ vi D:\toolkit\Ruby200\lib\ruby\gems\2.0.0\gems\jekyll-1.3.0\lib\jekyll\convertible.rb

#第38行,替换为下面内容
self.content = File.read_with_options(File.join(base, name), :encoding => "utf-8")

重启服务器


Administrator@PC201304202140 /d/workspace/ruby/jekyll
$ jekyll serve
Configuration file: d:/workspace/ruby/jekyll/_config.yml
            Source: d:/workspace/ruby/jekyll
       Destination: d:/workspace/ruby/jekyll/_site
      Generating...
 ___________________________________________________________________________
| Maruku tells you:
+---------------------------------------------------------------------------
| Could not find ref_id = "httpblogfensmejekyllbootstarpdoc" for md_link(["http:
//blog.fens.me/jekyll-bootstarp-doc/"],"httpblogfensmejekyllbootstarpdoc")
| Available refs are []
+---------------------------------------------------------------------------
!d:/toolkit/Ruby200/lib/ruby/gems/2.0.0/gems/maruku-0.6.1/lib/maruku/errors_mana
gement.rb:49:in `maruku_error'
!d:/toolkit/Ruby200/lib/ruby/gems/2.0.0/gems/maruku-0.6.1/lib/maruku/output/to_h
tml.rb:715:in `to_html_link'
!d:/toolkit/Ruby200/lib/ruby/gems/2.0.0/gems/maruku-0.6.1/lib/maruku/output/to_h
tml.rb:970:in `block in array_to_html'
!d:/toolkit/Ruby200/lib/ruby/gems/2.0.0/gems/maruku-0.6.1/lib/maruku/output/to_h
tml.rb:961:in `each'
!d:/toolkit/Ruby200/lib/ruby/gems/2.0.0/gems/maruku-0.6.1/lib/maruku/output/to_h
tml.rb:961:in `array_to_html'
\___________________________________________________________________________
Not creating a link for ref_id = "httpblogfensmejekyllbootstarpdoc".done.
    Server address: http://0.0.0.0:4000
  Server running... press ctrl-c to stop.

错误解决!

打开浏览器:http://localhost:4000/2013/11/06/hello-world/

jekyll-post-hello-world

2). 编写新页面(Create a Page)
通过命令生成页面


~ D:\workspace\ruby\jekyll>rake page name="about.md"
mkdir -p .
Creating new page: ./about.md

~ D:\workspace\ruby\jekyll>rake page name="pages/about"
mkdir -p ./pages/about
Creating new page: ./pages/about/index.html

同样,我们编辑文件,重启jekyii服务就行了。

5. 发布到Github

在github网站,我们创建一个新的库,jekyll-demo

把jekll项目,添加到jekyll-demo


~ D:\workspace\ruby\jekyll>git remote set-url origin git@github.com:bsspirit/jekyll-demo.git

~ D:\workspace\ruby\jekyll>git add .
~ D:\workspace\ruby\jekyll>git commit -m 'new_post'
[master 1fc298e] 'new_post'
 4 files changed, 36 insertions(+)
 create mode 100644 _posts/2013-11-06-hello-world.md
 create mode 100644 about.md
 create mode 100644 pages/about/index.html

~ D:\workspace\ruby\jekyll>git push origin master
Counting objects: 916, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (431/431), done.
Writing objects: 100% (916/916), 297.68 KiB, done.
Total 916 (delta 437), reused 879 (delta 422)
To git@github.com:bsspirit/jekyll-demo.git
 * [new branch]      master -> master

新建一个gh-pages分支,用于发布项目


~ git branch gh-pages
~ git checkout gh-pages

修改文件:_config.yml,设置base_path


~ vi _config.yml

production_url : http://bsspirit.github.io
BASE_PATH : /jekyll-demo

发布项目


~ git add .
~ git commit -m 'deploy'
~ git push origin gh-pages

发布需要10分钟,10分钟后,在github上面浏览项目,http://bsspirit.github.io/jekyll-demo

jekyll-bootstrap-github

项目地址的格式为:

http://[username].github.io/[projectname]/

这样我们就可以通过github构建免费的web应用了。

转载请注明出处:
http://blog.fens.me/jekyll-bootstarp-github/

打赏作者

Hadoop历史版本安装

Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, Pig, HBase, Sqoop, Mahout, Zookeeper, Avro, Ambari, Chukwa,新增加的项目包括,YARN, Hcatalog, Oozie, Cassandra, Hama, Whirr, Flume, Bigtop, Crunch, Hue等。

从2011年开始,中国进入大数据风起云涌的时代,以Hadoop为代表的家族软件,占据了大数据处理的广阔地盘。开源界及厂商,所有数据软件,无一不向Hadoop靠拢。Hadoop也从小众的高富帅领域,变成了大数据开发的标准。在Hadoop原有技术基础之上,出现了Hadoop家族产品,通过“大数据”概念不断创新,推出科技进步。

作为IT界的开发人员,我们也要跟上节奏,抓住机遇,跟着Hadoop一起雄起!

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/hadoop-history-source-install/

hadoop-history

前言

介绍Hadoop安装的文章,已经写过2篇了,老生常谈的话题又被拿出来了。这次要重新安装Hadoop-1.1.2的历史版本,来满足Mahout-0.8版本的依赖要求。本来只想简单说几句,不过遇到了几个小问题,因此写篇文章总结一下吧。

Hadoop安装的其他文章:

目录

  1. 找到Hadoop历史版本
  2. 用源代码构建Hadoop环境
  3. 快速Hadoop配置环境脚本
  4. 为win环境编译hadoop-core.jar

1. 找到Hadoop历史版本

这里我需要的Hadoop版本是1.1.2。打开hadoop的下载页面

http://www.apache.org/dyn/closer.cgi/hadoop/common/

随便打开一个下载镜像,我们都找不到1.1.2这个版本。

hadoop-download

看看github上的情况

hadoop-github

找到release-1.1.2

https://github.com/apache/hadoop-common/releases/tag/release-1.1.2

下载源代码:

~ wget https://github.com/apache/hadoop-common/archive/release-1.1.2.tar.gz

查看branch-1.1

https://github.com/apache/hadoop-common/tree/branch-1.1

2. 用源代码构建Hadoop环境

注:github上面最新hadoop-3.0.0-SNAPSHOT,包结构已经完全改变,用Maven代替了Ant+Ivy的构建过程。

Linux系统环境:

  • Linux Ubuntu 64bit Server 12.04.2 LTS
  • Java 1.6.0_29
  • Ant 1.8.4

安装Hadoop


~ tar xvf release-1.1.2.tar.gz
~ mkdir /home/conan/hadoop/
~ mv hadoop-common-release-1.1.2 /home/conan/hadoop/
~ cd /home/conan/hadoop/
~ mv hadoop-common-release-1.1.2/ hadoop-1.1.2

查看hadoop目录


~ ls -l
total 648
drwxrwxr-x  2 conan conan   4096 Mar  6  2013 bin
-rw-rw-r--  1 conan conan 120025 Mar  6  2013 build.xml
-rw-rw-r--  1 conan conan 467130 Mar  6  2013 CHANGES.txt
drwxrwxr-x  2 conan conan   4096 Oct  3 02:31 conf
drwxrwxr-x  2 conan conan   4096 Oct  3 02:28 ivy
-rw-rw-r--  1 conan conan  10525 Mar  6  2013 ivy.xml
drwxrwxr-x  4 conan conan   4096 Mar  6  2013 lib
-rw-rw-r--  1 conan conan  13366 Mar  6  2013 LICENSE.txt
drwxrwxr-x  2 conan conan   4096 Oct  3 03:35 logs
-rw-rw-r--  1 conan conan    101 Mar  6  2013 NOTICE.txt
-rw-rw-r--  1 conan conan   1366 Mar  6  2013 README.txt
-rw-rw-r--  1 conan conan   7815 Mar  6  2013 sample-conf.tgz
drwxrwxr-x 16 conan conan   4096 Mar  6  2013 src

在根目录下面,没有hadoop-*.jar的各种类库,也没有依赖库。

执行Ant进行编译

从Ant官方网站下载Ant, http://ant.apache.org/bindownload.cgi


~ wget http://archive.apache.org/dist/ant/binaries/apache-ant-1.8.4-bin.tar.gz
~ tar xvf apache-ant-1.8.4-bin.tar.gz
~ mkdir /home/conan/toolkit/
~ mv apache-ant-1.8.4 /home/conan/toolkit/
~ cd /home/conan/toolkit/
~ mv apache-ant-1.8.4 ant184

设置ant到环境变量


# 编辑environment文件
~  sudo vi /etc/environment

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/conan/toolkit/jdk16/bin:/home/conan/toolkit/ant184/bin"

JAVA_HOME=/home/conan/toolkit/jdk16
ANT_HOME=/home/conan/toolkit/ant184

#让环境变量生效
~ . /etc/environment

#运行ant命令,检查环境变量是否配置成功
~ ant
Buildfile: build.xml does not exist!
Build failed

用Ant编译Hadoop


# 安装编译用的库
~ sudo apt-get install autoconf
~ sudo apt-get install libtool

# 用Ant编译Hadoop
~ cd /home/conan/hadoop/hadoop-1.1.2/
~ ant

要等几分钟,然后build成功。

查看生成的build目录


~ ls -l build
drwxrwxr-x  3 conan conan    4096 Oct  3 04:06 ant
drwxrwxr-x  2 conan conan    4096 Oct  3 04:02 c++
drwxrwxr-x  3 conan conan    4096 Oct  3 04:05 classes
drwxrwxr-x 13 conan conan    4096 Oct  3 04:06 contrib
drwxrwxr-x  2 conan conan    4096 Oct  3 04:05 empty
drwxrwxr-x  2 conan conan    4096 Oct  3 04:02 examples
-rw-rw-r--  1 conan conan     423 Oct  3 04:05 hadoop-client-1.1.3-SNAPSHOT.jar
-rw-rw-r--  1 conan conan 4035744 Oct  3 04:05 hadoop-core-1.1.3-SNAPSHOT.jar
-rw-rw-r--  1 conan conan     426 Oct  3 04:05 hadoop-minicluster-1.1.3-SNAPSHOT.jar
-rw-rw-r--  1 conan conan  306827 Oct  3 04:05 hadoop-tools-1.1.3-SNAPSHOT.jar
drwxrwxr-x  4 conan conan    4096 Oct  3 04:02 ivy
drwxrwxr-x  3 conan conan    4096 Oct  3 04:02 src
drwxrwxr-x  6 conan conan    4096 Oct  3 04:02 test
drwxrwxr-x  3 conan conan    4096 Oct  3 04:05 tools
drwxrwxr-x  9 conan conan    4096 Oct  3 04:02 webapps

发现hadoop-*.jar都是hadoop-*-1.1.3-SNAPSHOT.jar结尾的,合理的解释就是:上一个版本的release就是下一个版本的SNAPSHOT。

我们修改一下build.xml文件31行,把包名改成hadoop-*-1.1.2.jar,再重新ant


~ vi build.xml

~ rm -rf build
~ ant

把生成的hadoop-*-1.1.2.jar复制到根目录


~ cp build/*.jar .
~ ls -l
drwxrwxr-x  2 conan conan    4096 Oct  3 04:24 bin
drwxrwxr-x 13 conan conan    4096 Oct  3 04:21 build
-rw-rw-r--  1 conan conan  120016 Oct  3 04:20 build.xml
-rw-rw-r--  1 conan conan  467130 Mar  6  2013 CHANGES.txt
drwxrwxr-x  2 conan conan    4096 Oct  3 02:31 conf
-rw-rw-r--  1 conan conan     414 Oct  3 04:24 hadoop-client-1.1.2.jar
-rw-rw-r--  1 conan conan 4035726 Oct  3 04:24 hadoop-core-1.1.2.jar
-rw-rw-r--  1 conan conan     417 Oct  3 04:24 hadoop-minicluster-1.1.2.jar
-rw-rw-r--  1 conan conan  306827 Oct  3 04:24 hadoop-tools-1.1.2.jar
drwxrwxr-x  2 conan conan    4096 Oct  3 02:28 ivy
-rw-rw-r--  1 conan conan   10525 Mar  6  2013 ivy.xml
drwxrwxr-x  4 conan conan    4096 Mar  6  2013 lib
-rw-rw-r--  1 conan conan   13366 Mar  6  2013 LICENSE.txt
drwxrwxr-x  3 conan conan    4096 Oct  3 04:28 logs
-rw-rw-r--  1 conan conan     101 Mar  6  2013 NOTICE.txt
-rw-rw-r--  1 conan conan    1366 Mar  6  2013 README.txt
-rw-rw-r--  1 conan conan    7815 Mar  6  2013 sample-conf.tgz
drwxrwxr-x 16 conan conan    4096 Mar  6  2013 src

这个就生成好了,hadoop环境,和我们之前下载的就一样了。

3. 快速Hadoop配置环境脚本

  • 1. 配置环境变量
  • 2. Hadoop的3个配置文件
  • 3. 创建Hadoop目录
  • 4. 配置hostname和hosts
  • 5. 生成SSH免登陆
  • 6. 第一次启动格式化HDFS
  • 7. 启动Hadoop的服务

下面的脚本要写在一起


~ sudo vi /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/conan/toolkit/jdk16/bin:/home/conan/toolkit/ant184/bin:/home/conan/toolkit/maven3/bin:/home/conan/toolkit/tomcat7/bin:/home/conan/hadoop/hadoop-1.1.2/bin"
JAVA_HOME=/home/conan/toolkit/jdk16
ANT_HOME=/home/conan/toolkit/ant184
MAVEN_HOME=/home/conan/toolkit/maven3
NUTCH_HOME=/home/conan/toolkit/nutch16
TOMCAT_HOME=/home/conan/toolkit/tomcat7
HADOOP_HOME=/home/conan/hadoop/hadoop-1.1.2
HADOOP_CMD=/home/conan/hadoop/hadoop-1.1.2/bin/hadoop
HADOOP_STREAMING=/home/conan/hadoop/hadoop-1.1.2/contrib/streaming/hadoop-streaming-1.1.2.jar

~ . /etc/environment

~ vi conf/core-site.xml
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://master:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/conan/hadoop/tmp</value>
</property>
<property>
<name>io.sort.mb</name>
<value>256</value>
</property>
</configuration>

~ vi conf/hdfs-site.xml
<configuration>
<property>
<name>dfs.data.dir</name>
<value>/home/conan/hadoop/data</value>
</property>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
</configuration>

~ vi conf/mapred-site.xml
<configuration>
<property>
<name>mapred.job.tracker</name>
<value>hdfs://master:9001</value>
</property>
</configuration>

~ mkdir /home/conan/hadoop/data
~ mkdir /home/conan/hadoop/tmp
~ sudo chmod 755 /home/conan/hadoop/data/
~ sudo chmod 755 /home/conan/hadoop/tmp/

~ sudo hostname master
~ sudo vi /etc/hosts
192.168.1.210   master
127.0.0.1       localhost

~ ssh-keygen -t rsa
~ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

~ bin/hadoop namenode -format
~ bin/start-all.sh

检查hadoop运行状态


~ jps
15574 DataNode
16324 Jps
15858 SecondaryNameNode
16241 TaskTracker
15283 NameNode
15942 JobTracker

~ bin/hadoop dfsadmin -report
Configured Capacity: 18751434752 (17.46 GB)
Present Capacity: 14577520655 (13.58 GB)
DFS Remaining: 14577491968 (13.58 GB)
DFS Used: 28687 (28.01 KB)
DFS Used%: 0%
Under replicated blocks: 0
Blocks with corrupt replicas: 0
Missing blocks: 0

-------------------------------------------------
Datanodes available: 1 (1 total, 0 dead)

Name: 192.168.1.210:50010
Decommission Status : Normal
Configured Capacity: 18751434752 (17.46 GB)
DFS Used: 28687 (28.01 KB)
Non DFS Used: 4173914097 (3.89 GB)
DFS Remaining: 14577491968(13.58 GB)
DFS Used%: 0%
DFS Remaining%: 77.74%
Last contact: Thu Oct 03 05:03:50 CST 2013

4. 为win环境编译hadoop-core.jar

在win环境开发中,经常会遇到一个错误权限检查的异常,我们需要修改FileUtil.java文件,注释688行–693行。

hadoop-win-code


~ vi src/core/org/apache/hadoop/fs/FileUtil.java

685 private static void checkReturnValue(boolean rv, File p,
686                                        FsPermission permission
687                                        ) throws IOException {
688   /*  if (!rv) {
689       throw new IOException("Failed to set permissions of path: " + p +
690                             " to " +
691                             String.format("%04o", permission.toShort()));
692     }
693   */
694   }

用ant重新打包后,就生成了可以在win运行的hadoop-core-1.1.2.jar!使用方法可以参考文章:用Maven构建Hadoop项目,我们后面一直会用到!

转载请注明出处:
http://blog.fens.me/hadoop-history-source-install/

打赏作者