golang gmail API

2014年10月23日 10:30

package main

import (
"flag"
"fmt"
"log"
"net/http"
"strings"

"code.google.com/p/goauth2/oauth"
gmail "code.google.com/p/google-api-go-client/gmail/v1"
)

var (
code      = flag.String("code", "", "Authorization Code")
cachefile = flag.String("cache", "cache.json", "Token cache file")
)

const usageMsg = `
To obtain a request token you must specify both -id and -secret.

To obtain Client ID and Secret, see the "OAuth 2 Credentials" section under
the "API Access" tab on this page: https://console.developers.google.com/

Once you have completed the OAuth flow, the credentials should be stored inside
the file specified by -cache and you may run without the -id and -secret flags.
`

func main() {
flag.Parse()
var config = &oauth.Config{
ClientId:     "",// https://console.developers.google.com/ 新建一个project 后,申请一个oauth 的clientId
ClientSecret: "",// 和ClientSecret
Scope:        gmail.MailGoogleComScope,
RedirectURL:  "urn:ietf:wg:oauth:2.0:oob",
AuthURL:      "https://accounts.google.com/o/oauth2/auth",
TokenURL:     "https://accounts.google.com/o/oauth2/token",
TokenCache:   oauth.CacheFile(*cachefile),
}

client, err := GetOauthClient(config)
if err != nil {
return
}
svc, err := gmail.New(client)
labelId := GetLabelId(svc, "LabelName") // LabelName 替换为gmail 中的label
ScanMessage(svc, labelId)
}

// chan 的设置仍然大了点,超过了google 的api rate limit……
var ch_pages = make(chan string, 5) // NextPageToken的chan
var ch_messageIds = make(chan string, 5) // MessageId的chan

var done = make(chan int) // 未正确使用……

func ScanMessage(svc *gmail.Service, labelId string) {
resp, err := svc.Users.Messages.List("me").LabelIds(labelId).Do()
if err != nil {
log.Fatal(err)
}

if len(resp.NextPageToken) > 0 {
ch_pages <- resp.NextPageToken
}

go func(svc *gmail.Service) {
for {
select {
case resp := <-ch_pages:
go GetPages(svc, resp, labelId)
case msgId := <-ch_messageIds:
go CheckMailMessage(svc, msgId)
}
}
}(svc)

for _, message := range resp.Messages {
ch_messageIds <- message.Id
}

<-done
log.Println("all mail chceked!")
}

// 请求下一页
func GetPages(svc *gmail.Service, pageToken string, labelId string) {
log.Println("PageToken:", pageToken)
resp, err := svc.Users.Messages.List("me").LabelIds(labelId).PageToken(pageToken).Do()
if err != nil {
log.Fatal(err)
}
for _, message := range resp.Messages {
ch_messageIds <- message.Id
}
if len(resp.NextPageToken) > 0 {
ch_pages <- resp.NextPageToken
} else {
done <- 1
}
}

// 请求具体的Message,这里只获取一下From 和Subject 作为判断依据
func CheckMailMessage(svc *gmail.Service, msgId string) {
log.Println("Message.Id:", msgId)
msg, err := svc.Users.Messages.Get("me", msgId).Do()
if err != nil {
log.Fatal(err)
}
var from, subject string
for _, h := range msg.Payload.Headers {
if h.Name == "From" {
lIdx := strings.Index(h.Value, "<")
rIdx := strings.Index(h.Value, ">")
if lIdx > 0 && rIdx < len(h.Value) {
from = strings.TrimSpace(h.Value[lIdx+1 : rIdx])
}
}
if h.Name == "Subject" {
tmp := strings.Split(h.Value, " ")
subject = tmp[len(tmp)-1]
}
}

log.Println(subject, from)

trash := Check(from, subject)
if trash {
log.Println(subject, from, trash)
svc.Users.Messages.Trash("me", msg.Id).Do()
}
}

// 具体的判断规则
func Check(from, subject string) bool {
if from == "xxx@gmail.com" {
return true
}
return false
}

// 根据labelName 获得LabelId
func GetLabelId(svc *gmail.Service, label string) (labelId string) {
list, err := svc.Users.Labels.List("me").Do()
if err != nil {
log.Fatal(err)
}
for _, lbl := range list.Labels { // 可以修改这里,看看你gmail 中所有label 对应的label id
if lbl.Name == label {
labelId = lbl.Id
break
}
}
return
}

// 抄来的oauth 登陆部分
func GetOauthClient(config *oauth.Config) (*http.Client, error) {
transport := &oauth.Transport{Config: config}
// Try to pull the token from the cache; if this fails, we need to get one.
token, err := config.TokenCache.Token()
if err != nil {
if *code == "" {
// Get an authorization code from the data provider.
// ("Please ask the user if I can access this resource.")
url := config.AuthCodeURL("")
fmt.Print("Visit this URL to get a code, then run again with -code=YOUR_CODE\n\n")
fmt.Println(url)
return nil, err
}
// Exchange the authorization code for an access token.
// ("Here's the code you gave the user, now give me a token!")
token, err = transport.Exchange(*code)
if err != nil {
log.Fatal("Exchange:", err)
}
// (The Exchange method will automatically cache the token.)
fmt.Printf("Token is cached in %v\n", config.TokenCache)
}

// Make the actual request using the cached token to authenticate.
// ("Here's the token, let me in!")
transport.Token = token

// Make the request.
return transport.Client(), nil
}

 

Tags: go, gmail, google-api
评论(0) 阅读(465)

不要给自己家里的设备绑域名

2013年2月01日 09:11

我的情况是:


家里是树莓派上跑支持spdy的nginx,平时用迅雷离线脚本下电影啥的。
绑域名是为了方便在单位连回去,比用ip方便,比如nginx可以挂多个2级域名,否则就得改n行hosts,ssh连解也不用每次都yes了。
 
然后上上周我妈说接到电信电话说要求停掉家里的web server。当时想大概是dnspod的监控太平凡访问了,就把监控停了。
之后相安无事,直到昨天中午家里来电话表示连iptv都不能看了,iptv显示账号不存在或已停机。
 
然后下班回家询问10000号,对方表示这个关停账户的动作不是他们公司的行为,是某个网络信息办公室的行为,原因是违法违规使用互联网。
具体就是不允许在家用动态ip上绑定域名……
 
目前该办公室已发出整改通知书,待到整改通知书收到后,需按照通知书上说明到某处处理后,上级会决定是否允许恢复网络…
 
虽然我估计应该不会再有像我这么2的User了,但是遇上这个事,我也实在是不吐不快啊……虽然完全想不到嘈。
 
大概会在收到通知书后继续更新后续。
 

评论(0) 阅读(1010)

FAQ: How do I add a venue on foursquare?

2012年12月20日 15:31

http://aboutfoursquare.com/faq-how-do-i-add-a-venue-on-foursquare/

you have to search for the venue first.

困扰了我大约2周的问题终于得解……

评论(0) 阅读(823)

发现一个vs.net2003的bug

2012年5月08日 09:17

这个大概应该算是由于我错误的使用导致发现的bug吧

情况是这样的:

  • 历史遗留项目需要vs.net2003(正在努力设法使项目脱离ide,显然的好处是可以自动构建了)
  • 有一些超长的sql语句,原本是用字符串拼接的,现在改为使用sql参数来传递查询参数,于是sql语句本身就可以是常量了

sql语句本身改为常量(const string)后,问题出现了

  • 尝试debug时,ide自动消失,完全无法
  • 观察后,也不是立即消失,而是在编译中的某一步时消失
  • 继续观察实验后,确定只要编译选项中开启了"生成调试信息"这个选项(设置为true),就必定会消失,不论是Debug还是Release.反之,只要为关闭,则都可以完成编译
  • 这个选项真的不能进行debug了...

然后将解决方案中无关项目(能正常编译的项目)全部remove,再把问题项目中的所有代码注释掉,一次只放开一个方法,反复编译, 最终确定是const string太长导致的,去掉const关键字后,就正常了.

然后又试着直接csc命令行编译,不报错,正常通过

所以,这是个vs.net2003的bug吧.

评论(0) 阅读(1010)

密码

2011年12月27日 20:39

最近密码泄露的问题暂时还止不住啊

然后也出现了好多讨论密码的文章

多数是在假设所有运营商都是好人的前提下(他们加密,加盐,算法不可逆,各种防范措施周全),如何设置个好密码。

比如,设置多少长度,使用各种奇怪的字符等

我想,其实,如果密码可以输入中文的话,问题就解决了……

哪怕是4字密码,常用字3000的情况下,只要不是常用的词组,那就够破解者抓狂了

而且,中文输入法重码+现在的输入法都有自动排序常用字的情况,即使有键盘记录软件记录下击键全程,但因为没有个性化的码表,也无法获得真正输入的密码,至少没那么直接。

不过到时候怎么输入又是个问题了,呵呵。索性直接汉语拼音输入,长度估计也足够了。

评论(0) 阅读(1290)

从MySql 数据库迁移到MS Sql Server

2011年6月24日 11:29

 

有很多种方法
仅供参考
首先介绍最麻烦的方法

最麻烦的方法,也是最通用的方法

通用到可以从MySql迁移到任意数据库,麻烦到每一步都得亲历亲为
mysql命令行工具里有个mysqldump.exe,应该就在mysql安装目录下的bin目录下
用它可以将任意数据库dump出来
dump出来的是文本文件(但由于大小,可能你的文本编辑器永远也打不开它)
其中包含了完整的,使用ddl描述的数据库信息,以及使用sql insert语句描述的所有数据
所以,我们可以用dump文件中的信息,手工的在任意数据库中建立起tables,然后用insert语句(当然的需要适当的修改语法,有时候仅需正则表达式替换)将所有数据恢复出来
完成

简单的方法,微软的方法

微软自2010年12月起提供了mysql到sqlserver的工具
去搜索SSMA for MySQL或者Microsoft SQL Server Migration Assistant for MySQL
写此文时,版本是5.0,2011年4月推出的
支持从4.1起到6.0的mysql,同时支持2005和2008系列sqlserver
下载下安装包(.zip文件)后,会有两个文件,其中那个Extension Pack不知道是干啥的...
反正我们用SSMA for MySql 5.0.exe就是了.安装它
然后仅凭直觉使用它

我是说,在开始菜单里找到并启动Microsoft SQL Server Migration Assistant for MySQL
第一次启动会要求你给它一个license,点击弹出框的那个链接,然后用你msn的帐号去微软官方网站申请一个就是了,不要钱,然后放到指定目录下,点击reflash license按钮,它就会乖乖的工作了.
然后在File菜单里新建一个工程/项目
然后分别点击工具栏上的Connect to MySql和Connect to SQL Server按钮,其中会想你询问两个数据库的位置,密码等
成功连接后,选择MySql中希望迁移到SQL Server的数据库,右键,Migrate Data
登登~完成了
事后会出一份report,告诉你数据库下各个表的迁移情况

评论(0) 阅读(4077)

版权是怎么回事?

2011年4月27日 09:34

 

我现在完全想不明白版权这件事.
比如,借阅,分享纸质书是因为没有发生复制和或再分发,所以不侵权.
这里,分享了,但没有复制.是允许的.
所以认为版权侵权在复制时发生?
 
那么,我将我购买回来的书籍(数字信息)备份(不止一份,并备份在任意多个地点),但不分发,是否算复制,是否侵权?
如果不算侵权,那么侵权就在于是否将这些复制再分发?
 
还是说未经允许的复制和或分发都是侵权?哪怕只是备份?
 
一系列自问后,我觉得我有点想明白了
 
比如,我认为未经允许的复制和或分享就是侵权.
 
然后注意到自己在提问时使用了分享和分发
所以要明确分享和分发到概念
分享是无复制发生的
分发是由复制发生的
所以网络上的共享就是复制分发,就有可能是侵权
 
但是显然,分享由于无复制发送,其分享范围有限,最终不会使发行商受到大的影响,所以被放过
分发则可能造成,实际上,也主要打击那些造成了大规模分享,并且因此损害到发行商的实际利益时
 
但是还是有些问题没想明白
比如,在商场播放音乐为何会发生版权问题?
商场买的都是盗版音乐?
是看/听的人,实现了脑内复制,还是分发给了多个耳朵?
 
一样的KTV为何会被收版权使用费?他们购买的时候没有付这个费?
还是,版权里不包括使用权?那么买回来的书要怎么看?
 
最后,数字时代的分享总是意味着复制,那为何数字媒体仍然要使用纸媒的版权概念?
 

评论(1) 阅读(1648)

.net 操作excel对象并保持,需要做的设置

2011年3月14日 16:11

1. Login to the server as a administrator.
2. Go to "Start" -> "Run" and enter "taskmgr"
3. Go to the process tab in task manager and check "Show Processes from all
users"
4. If there are any "Excel.exe" entries on the list, right click on the
entry and select "End Process"
5. Close task manager.
6. Go to "Start" -> "Run" and enter "services.msc"
7. Stop the service automating Excel if it is running.
8. Go to "Start" -> "Run" and enter "dcomcnfg"
9. This will bring up the component services window, expand out "Console
Root" -> "Computers" -> "DCOM Config"
10. Find "Microsoft Excel Application" in the list of components.
11. Right click on the entry and select "Properties"
12. Go to the "Identity" tab on the properties dialog.
13. Select "The interactive user."
14. Click the "OK" button.
15. Switch to the services console
16. Start the service automating Excel
17. Test you application again.

评论(0) 阅读(1658)

换arch玩玩吧

2011年3月07日 20:26

又一次的把ubuntu给玩坏了,而且又一次不知道怎么修复……

在这11.04还没多久就要出来的时间点上,真尴尬……

算了,换arch 玩玩吧,说不定会终于有些长进……

而且,我想要gnome-shell,我觉得比那ubuntu的新界面舒服的多

评论(1) 阅读(1736)

Hosting Git Repository in Windows

2011年3月03日 01:25

Hosting Git Repository in Windows

 

打开cygwin的shell

在/usr/bin目录下新建gitd

其中内容为

 

#!/bin/bash

git daemon --reuseaddr --base-path=/git --export-all --verbose --enable=receive-pack

在shell中运行命令

 

cygrunsrv   --install gitd                          \
            --path /bin/bash.exe           \
            --args /usr/bin/gitd           \
            --desc "Git Daemon"                     \
            --neverexits                            \
            --shutdown

再运行

cygrunsrv --start gitd

启动服务

如此以上,完成

评论(0) 阅读(1915)