package main





import (

"html/template"

"io"

"io/ioutil"

"log"

"net/http"

"os"

"path"

"runtime/debug"

)





const (

ListDir      = 0x0001

UPLOAD_DIR   = "./uploads"

TEMPLATE_DIR = "./views"

)





//cache storage all template

var templates = make(map[string]*template.Template)





func init() {

fileInfoArr, err := ioutil.ReadDir(TEMPLATE_DIR)

check(err)

var templateName, templatePath string

for _, fileInfo := range fileInfoArr {

templateName = fileInfo.Name()

if ext := path.Ext(templateName); ext != ".html" {

continue

}

templatePath = TEMPLATE_DIR + "/" + templateName

//log.Println(templateName)

log.Println("Loading template:", templatePath)

t := template.Must(template.ParseFiles(templatePath))

templates[templateName] = t

}





//if const template

/*for _, tmpl := range []string{"upload", "list"} {

//Must ensure in case can't analytic will do error operate,If the template loading is not successful, the program will exit

t := template.Must(template.ParseFiles(tmpl + ".html"))

templates[tmpl] = t

}*/

}

func check(err error) {

if err != nil {

panic(err)

}

}

func renderHtml(w http.ResponseWriter, tmpl string, locals map[string]interface{}) {

/*tt := templates[tmpl]

log.Println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", templates, tmpl, tt)*/

log.Println(locals)

err := templates[tmpl].Execute(w, locals)





check(err)

}

func isExists(path string) bool {

_, err := os.Stat(path)

//log.Println(err)

if err == nil {

return true

}

return os.IsExist(err)

}





//Callback method,

func uploadHandler(w http.ResponseWriter, r *http.Request) {

//log.Println(r.Method)

if r.Method == "GET" {

renderHtml(w, "upload.html", nil)

}

if r.Method == "POST" {

f, h, err := r.FormFile("image")

//log.Println(f, h, err)

check(err)

filename := h.Filename

defer f.Close()

//log.Println(UPLOAD_DIR, filename)

t, err := ioutil.TempFile(UPLOAD_DIR, filename)

//log.Println(t)

check(err)

defer t.Close()

_, err = io.Copy(t, f) //dst src

check(err)

http.Redirect(w, r, "/view?

id="+filename, http.StatusFound)





}

}

func viewHandler(w http.ResponseWriter, r *http.Request) {

imageId := r.FormValue("id")

imagePath := UPLOAD_DIR + "/" + imageId

log.Println(imageId, imagePath)

if exists := isExists(imagePath); !exists {

http.NotFound(w, r)

return

}

//log.Println("222222222222")

w.Header().Set("Content-Type", "image")

http.ServeFile(w, r, imagePath)

}

func listHandler(w http.ResponseWriter, r *http.Request) {

fileInfoArr, err := ioutil.ReadDir("./uploads")

//log.Println(fileInfoArr)

check(err)

if err != nil {

http.Error(w, err.Error(), http.StatusInternalServerError)

return

}

locals := make(map[string]interface{})

images := []string{}

for _, fileInfo := range fileInfoArr {

//log.Println(fileInfo)

images = append(images, fileInfo.Name())

}

locals["images"] = images //这里map的key是images,相应list.html里面的$.images

renderHtml(w, "list.html", locals)





}



//巧用闭包避免执行时错误崩溃

func safeHandler(fn http.HandlerFunc) http.HandlerFunc {





return func(w http.ResponseWriter, r *http.Request) {

defer func() {

log.Println("can't past execute or finished execute")

if e, ok := recover().(error); ok {

log.Println("50x error")

//50x error

http.Error(w, e.Error(), http.StatusInternalServerError)

log.Println("Warn : panic in %v. - %v", fn, e)

log.Println(string(debug.Stack()))

}

}()





log.Println("if no panic then first execute")

fn(w, r)

}

}

func staticDirHandler(mux *http.ServeMux, prefix string, staticDir string, flags int) {

mux.HandleFunc(prefix, func(w http.ResponseWriter, r *http.Request) {

file := staticDir + r.URL.Path[len(prefix)-1:]

if (flags & ListDir) == 0 {

if exists := isExists(file); !exists {

http.NotFound(w, r)

return

}

}

http.ServeFile(w, r, file)

})





}

func main() {

mux := http.NewServeMux()

staticDirHandler(mux, "/assets/", "./public", 0)

mux.HandleFunc("/", safeHandler(listHandler))

mux.HandleFunc("/view", safeHandler(viewHandler))

mux.HandleFunc("/upload", safeHandler(uploadHandler))

err := http.ListenAndServe(":8080", mux)

if err != nil {

log.Fatal("ListenAndServe:", err.Error())

}

}

uoload.html

<html>

<head>

<meta charset="utf-8">

<title>upload</title>

</head>

<body>

<form method="POST" action="/upload" enctype="multipart/form-data">

choosing an image to upload :<br>

<input name="image" type="file">

<input type="submit" value="Upload">

</form>

</body>

</html>

list.html

<html>

<head>

<meta charset="utf-8">

<title>list</title>

</head>

<body>

<ol>

{{range $.images}}

<li><a href="/view?id={{.|urlquery}}">{{.|html}}</a></li>

{{end}}

</ol>

</body>

</html>

注意文件结构

photoweb

-photoweb.go

-public

-js

-css

-images

-uploads

-views

-upload.html

-list.html

解决调用七牛音频问题

演示样例仅仅提供代码方式调用api,不可以像图片处理直接在url中加入參数进行改动

若强用url会提示要预处理音频转码。一般转码採用异步方式

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbmVlZGthbmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

OK,在go的SDK代码中进行,结果发现api给的參数仅仅是个大概,go的api里面的相应參数。不全然和官网贴出来的一样

我们搜需PutPolicy

在rs/token.go 中,看到相应deadline。grep 'xx' *  -R查看文件中内容

package main





import (

"fmt"

. "github.com/qiniu/api/conf"

"github.com/qiniu/api/fop"

"github.com/qiniu/api/io"

"github.com/qiniu/api/rs"

"log"

)





func init() {





ACCESS_KEY = "自己的ak"

SECRET_KEY = "自己sk"

}





//GET upload access token

func uptoken(bucketName string) string {

putPolicy := rs.PutPolicy{

Scope: bucketName,

//CallbackUrl: callbackUrl,

//CallbackBody:callbackBody,

//ReturnUrl: returnUrl,

//ReturnBody: returnBody,

//AsyncOps: asyncOps,

//EndUser: endUser,

//Expires: expires,

Expires:             1406555272, //截止时间戳

PersistentOps:       "avthumb/mp3",

PersistentNotifyUrl: "http://fake.com/qiniu/notify",

}

return putPolicy.Token(nil)

}





func main() {

//上传本地文件

upload("a")





//5.1 获取文件信息

//getFileInfo()





//6.1.1 查看图像属性

//imageAttr()





//5.2 删除文件

//delFile()





}





//6.1.1 查看图像属性

func imageAttr() {

var imageUrl = "http://needkane.qiniudn.com/kane2.jpg"

ii := fop.ImageInfo{}

infoRet, err := ii.Call(nil, imageUrl)

if err != nil {

// 产生错误

log.Println("fop getImageInfo failed:", err)

return

}





log.Println(infoRet.Height, infoRet.Width, infoRet.ColorModel, infoRet.Format)

}





func makeImageInfoUrl(imageUrl string) string {

ii := fop.ImageInfo{}

return ii.MakeRequest(imageUrl)

}





//5.2 删除文件

func delFile() {

bucket := "needkane"

key := "goupload.jpg"

var rsCli = rs.New(nil)





err := rsCli.Delete(nil, bucket, key)

if err != nil {

// 产生错误

log.Println("rs.Copy failed:", err)

return

}

}





//5.1 获取文件信息

func getFileInfo() {

var ret rs.Entry

bucket := "needkane"

key := "kane3.jpg"

var rsCli = rs.New(nil)

var err error

ret, err = rsCli.Stat(nil, bucket, key)





if err != nil {

// 产生错误

log.Println("rs.Stat failed:", err)

return

}





// 处理返回值

log.Println(ret)

}





//上传本地文件

func upload(key string) {

uptoken := uptoken("needkane")

fmt.Printf("uptoken:%s\n", uptoken)





var err error

var ret io.PutRet

var extra = &io.PutExtra{

//Params: params,

//MimeType: mieType,

//Crc32: crc32,

//CheckCrc: CheckCrc,

}





var localFile = "/home/qboxtest/Downloads/a.wav"





// ret 变量用于存取返回的信息,详情见 io.PutRet

// uptoken 为业务server生成的上传口令

// key 为文件存储的标识

// localFile 为本地文件名称

// extra 为上传文件的额外信息。详情见 io.PutExtra,可选

err = io.PutFile(nil, &ret, uptoken, key, localFile, extra)





if err != nil {

//上传产生错误

log.Print("io.PutFile failed:", err)

return

}





//上传成功,处理返回值

log.Print(ret.Hash, ret.Key)





}

用 file 命令查看文件

第一个go的web程序;调用七牛云存储的音频api问题解决;条件搜寻文件中的内容,字符串拼接+在上一行的更多相关文章

  1. ueditor上传图片到七牛云存储(form api,java)

    转:http://my.oschina.net/duoduo3369/blog/174655 ueditor上传图片到七牛云存储 ueditor结合七牛传图片 七牛的试炼 开发前的准备与注意事项说明 ...

  2. 七牛云存储的 Javascript Web 前端文件上传

    因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,七牛云存储的 Web 前端文件上传 七牛是不错的云存储产品,特别是有免费的配额可 ...

  3. 代码实现:定义一个文件输入流,调用read(byte[] b)方法,将a.txt文件中的内容打印出来(byte数组大小限制为5)

    package com.loaderman.test; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; im ...

  4. CodeIgniter - 集成七牛云存储

    最近有一个项目需要集成七牛云存储的图片存储和调用功能,程序是基于CodeIgniter2.1.3的PHP框架.刚拿到手完全无从下手的感觉,因为像框架这种东西,想从官方的PHPSDK集成进去,需要改动很 ...

  5. Go语言实战 - 网站性能优化第一弹“七牛云存储”

    由于用户纷纷反应山坡网的打开速度比较慢,所以两天前我们决定把服务器从linode迁移到阿里云. 整个迁移过程非常平滑,基本上一个小时就完成了.而且阿里云的配套设施提供的也很不错,运行状态监控什么的都有 ...

  6. JavaWeb结合七牛云存储搭建个人相册服务

    JavaWeb结合七牛云存储搭建个人相册服务 一.引言1. 课程概述 相信很多人都知道网站一般会有很多图片,对于小型网站来说,图片放在网站服务器上不算什么,但当图片数量很大时,会造成服务器很臃肿,相应 ...

  7. 《介绍一款开源的类Excel电子表格软件》续:七牛云存储实战(C#)

    两个月前的发布的博客<介绍一款开源的类Excel电子表格软件>引起了热议:在博客园有近2000个View.超过20个评论. 同时有热心读者电话咨询如何能够在SpreadDesing中实现存 ...

  8. PHP使用七牛云存储之图片的上传、下载、303重定向教程,CI框架实例

    网上关于七牛云存储的教程除了官网上的API文档,其他的资料太少了.研究了下API之后,现在已经能实现图片的上传和下载及上传之后的重定向. http://blog.csdn.net/cqcre/arti ...

  9. wordpress使用video.js与七牛云存储实现无广告视频分享应用

    video.js是一款极受欢迎的基于HTML5的开源WEB视频播放器,其充分利用了HTML5的视频支持特性,可以实现全平台的无视频插件播放功能,对于现在流行的手机.PAD等移动智能终端有极佳的应用体验 ...

随机推荐

  1. OpenGL教程(25) skybox

    原帖地址:http://ogldev.atspace.co.uk/www/tutorial25/tutorial25.html Background A skybox is a technique t ...

  2. %date~0,4%和 %time~0,2%等用法详解(转)

    比如在windowscmd命令行窗口执行date命令后这个环境变量的值为当前日期:2014-09-01 星期六 或2014/09/01 周六那么如下的各个操作的意义如下:%date:~0,4% 表示从 ...

  3. 关于XSuperMES项目使用的AChartEngine图表引擎

     非常多时候项目中我们须要对一些统计数据进行绘制表格,更多直观查看报表分析 结果. 基本有以下几种方法: 1:能够进行android  api进行draw这种话.效率比較低 2:使用开源绘表引擎, ...

  4. 能够在Linux系统中运行的5款大型耐玩游戏

    Linux 可能不会很快成为游戏玩家选择的平台 —— Valve Steam Machines 的失败似乎是对这一点的深刻提醒 —— 但这并不意味着该平台没有稳定增长,并且拥有相当多的优秀游戏. 从独 ...

  5. installers PHPManager

    === Verbose logging started: // :: Build type: SHIP UNICODE 5.00.10011.00 Calling process: C:\Progra ...

  6. 一个小栗子聊聊JAVA泛型基础

    背景 周五本该是愉快的,可是今天花了一个早上查问题,为什么要花一个早上?我把原因总结为两点: 日志信息严重丢失,茫茫代码毫无头绪. 对泛型的认识不够,导致代码出现了BUG. 第一个原因可以通过以后编码 ...

  7. GitHub没有实时通知怎么办?当然是自己上手写一个啊!

    相信各位程序员对github已经不陌生了.不知道各位有没有注意到GitHub没有推送通知这个功能.当有人在我的存储库中创建了一个提取请求/问题时,我可以收到电子邮件通知,但当有人stars/forks ...

  8. Android 为何比 iOS 卡?【转载】

    Android 卡是必须的,当你的手机装了 20 多个 app,那不卡才叫见鬼了呢,我手机微信都打不开,手机直接自动重启啦~哪种东西生来就是完美的呢?即便是台式机,也是越用越慢.换句话,如果没有特别原 ...

  9. DELL平板如何安装WIN10系统-磁盘分区问题

    已经进入PE之后,在这一步的时候,可以把默认的系统分区都移除,但是在计算机管理可能右击没有这个菜单,要用专门的软件弄   不要用分区助手,会提示不能对动态磁盘进行操作,要用Disk Genius(他的 ...

  10. Discuz常见小问题-如何禁止调整宽屏模式

    在界面-界面设置中,可以勾选窄屏,不允许用户自由切换