使用 bitbucket REST API做个展示项目提交动态的WP模板页面

最近用上bitbucket了,github也有在用,不过它不允许免费用户创建private仓库。

bitbucket支持 Git和Mercurial两种类型的repo.且带Project management功能(Issue tracking+ Wiki),网页如同github一样,保持着简洁的特性。

bitbucket REST APIs 文档:http://confluence.atlassian.com/display/BITBUCKET/Using+the+bitbucket+REST+APIs

我这里只用到了Changesets REST resource
使用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ curl https://api.bitbucket.org/1.0/repositories/jespern/django-piston/changesets

{
    "count": 219,
    "start": "tip",
    "limit": 15,
    "changesets": [
        {
            "node": "21a24da68710",
            "files": [
                {
                    "type": "modified",
                    "file": "piston/oauth.py"
                }
            ],
            "author": "jespern",
            "timestamp": "2009-09-08 12:49:43",
            "branch": "default",
            "message": "oauth 1.0a spec ready oauth.py",
            "revision": 204,
            "size": 4166
        },
    ...
}

默认是返回json数据。
接口调用方式:

GET /repositories/USERNAME/REPO_SLUG/changesets
USERNAME: The owner username.
REPO_SLUG: The slug of the repository.

另外,还提供两个参数start 和 limit .
如,只取2条:

1
$ curl https://api.bitbucket.org/1.0/repositories/jespern/django-piston/changesets?limit=2

Authentication(认证)
对于public项目,以上这个调用是无需认证的,但是对于private repo,要获取数据就必须认证了。
认证方式可以采用HTTP BASIC AUTH 或 OAuth 1.0a . 为了避免要加载一个OAuth 类库,我这里就采用HTTP BASIC AUTH认证了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php
/*
Template Name: bitbucket
 */

?>
<?php
function get_bitbucket_changesets($userlogin,$password,$repo_admin='ihacklog', $repo ='hacklog-package', $limit = 10)
{
    global $wp_version;
    $changesets = array();
    $url = sprintf('https://api.bitbucket.org/1.0/repositories/%1$s/%2$s/changesets?limit=%3$d', $repo_admin, $repo,$limit );
    is_dir( WP_CONTENT_DIR .'/cache' ) || mkdir ( WP_CONTENT_DIR .'/cache/',0777, TRUE);
    $bitbucket_cache_file = WP_CONTENT_DIR .'/cache/'. md5($url);

    if( file_exists( $bitbucket_cache_file ) )
    {
        if( time() - filemtime($bitbucket_cache_file) > 3600* 1 )
        {
            unlink($bitbucket_cache_file);
        }
        else
        {
            $changesets = unserialize( base64_decode(file_get_contents($bitbucket_cache_file) ) );
        }
    }

    if( !is_array($changesets) || count($changesets) < 1 )
    {  
        //set up required options
        $ch = curl_init();
        curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 3 );
        curl_setopt( $ch, CURLOPT_TIMEOUT, 3 );
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
        curl_setopt( $ch, CURLOPT_USERAGENT, 'WordPress/' . $wp_version . '; ihacklog-WP-bitbucket-page-template-v1.0' );
        curl_setopt( $ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1 );
        curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt($ch,CURLOPT_USERPWD, $userlogin. ':' . $password);
        $data = curl_exec($ch);
        curl_close($ch);

        if( $data )
        {
            $arr = json_decode($data);
            $changesets = $arr->changesets;
        }
        file_put_contents($bitbucket_cache_file,base64_encode(serialize($changesets) ) );

    }

    foreach( $changesets as $change )
    {
        $change_url = sprintf('https://bitbucket.org/%1$s/%2$s/changeset/%3$s',$repo_admin,$repo, $change->node);
        $raw_author = explode(' ',$change->raw_author);
        echo '<p class="bitbucket-change">';
        echo '<span class="bitbucket-node"><a href="'. $change_url .'" title="by '. htmlspecialchars($raw_author[0]) .'" target="_blank">'. $change->node . '</a></span>';
        echo '<span class="bitbucket-utctime">' . gmdate('Y-m-d H:i:s',strtotime($change->utctimestamp) + 3600*8) .'</span>';
        echo '<span class="bitbucket-message">' .$change->message .'</span>';
        echo '</p>';
    }



}
?>
<?php get_header(); ?>
<?php
if(have_posts()) :
    the_post();
?>
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

    <h1 class="pagetitle"><?php the_title(); ?></h1>
    <!-- begin post -->
    <div class="entry page clear">
        <?php the_content(); ?>
        <style type="text/css" media="screen">
            p.bitbucket-change {
                margin:0;
            }
            .bitbucket-node , .bitbucket-utctime, .bitbucket-message {
                display: inline-block;
                margin:3px 5px;
            }
            .bitbucket-node {
                width:90px;
            }
            .bitbucket-utctime { width:140px;}
            .bitbucket-message { max-width:340px;}
        </style>

        <hr />
        <?php
        get_bitbucket_changesets('登录名','密码','REPO owner', 'REPO SLUG',10);
        ?>
        <hr />
    </div><!--end entry-->
</div><!--end post-->
   
    <!-- begin comments -->

        <?php //comments_template('', true); ?>

    <!-- end comments -->
   
    <?php else : ?>
    <div class="notfound">
        <h2>Not Found</h2>
        <p>Sorry, but you are looking for something that is not here.</p>
    </div>
    <?php endif; ?>

</div><!--end content-->
<?php get_sidebar(); ?>
<?php get_footer(); ?>
更多
One Response Post a comment

Leave a Reply

Note: You may use basic HTML in your comments. Your email address will not be published.

Subscribe to this comment feed via RSS