Skip to content

Commit

Permalink
GitHubGit: roughly compatible with jekyll
Browse files Browse the repository at this point in the history
Use the same jekyll structures, so you can post on jekyll and typecho
at same time.

- Only watch files in `_posts`.
- Add markdown support.
- Support jekyll style YAML fronter.
  • Loading branch information
weakish committed Dec 18, 2013
1 parent 5ff8420 commit 03c579a
Show file tree
Hide file tree
Showing 4 changed files with 1,252 additions and 104 deletions.
163 changes: 73 additions & 90 deletions GitHubGit/Action.php
Original file line number Diff line number Diff line change
@@ -1,117 +1,77 @@
<?php

require_once "Spyc.php";

class GitHubGit_Action extends Widget_Abstract_Contents implements Widget_Interface_Do
{

public function action()
{
/** get added files */

// GitHub webhooks
// https://help.github.com/articles/post-receive-hooks
$get_payload = function () {

/** get added files
GitHub webhooks
https://help.github.com/articles/post-receive-hooks
**/

$payload = ltrim(urldecode(file_get_contents('php://input')), 'payload=');
$data = json_decode($payload, true); //without `true`, json_decode will return object instead of array
$repository_url = $data['repository']['url'];
return $data;
};

$data = $get_payload();


$get_added_files = function ($data) {

$commits = $data['commits'];
foreach ($commits as $commit) {
foreach ($commit['added'] as $added_file) {
$added_files[] = $added_file;
if (preg_match('#^_posts/#', $added_file)) {
$added_files[] = $added_file;
}
}
}

return $added_files;
};

/** login */
$master = $this->db->fetchRow($this->db->select()->from('table.users')
->where('group = ?', 'administrator')
->order('uid', Typecho_Db::SORT_ASC)
->limit(1));

if (empty($master)) {
return false;
} else if (!$this->user->simpleLogin($master['uid'])) {
return false;
}
$added_files = $get_added_files($data);

/** add article */
if (isset($added_files) && is_array($added_files)) {
foreach ($added_files as $added_file) {

$input = array(
'do' => 'publish',
'allowComment' => $this->options->defaultAllowComment,
'allowPing' => $this->options->defaultAllowPing,
'allowFeed' => $this->options->defaultAllowFeed
);
$get_repository_url = function ($data) {
return $repository_url = $data['repository']['url'];
};

list($slug) = explode('.', basename($added_file));
$input['slug'] = $slug;
$repository_prefix = preg_replace('#https://#', 'https://raw.', $get_repository_url($data));

$post = $this->db->fetchRow($this->db->select()
->from('table.contents')->where('slug = ?', $slug)->limit(1));
if (!empty($post)) {
if ('post' != $post['type']) {
return false;
} else {
$input['cid'] = $post['cid'];
}
}

$input['category'] = 'default';
$input['title'] = pathinfo($added_file)['filename'];
$url = preg_replace('#https://#', 'https://raw.', $repository_url) . '/master/' . $added_file;
$input['text'] = file_get_contents($url);
if ($input) {
$this->widget('Widget_Contents_Post_Edit', NULL, $input, false)->action();
$login = function () {
$master = $this->db->fetchRow($this->db->select()->from('table.users')
->where('group = ?', 'administrator')
->order('uid', Typecho_Db::SORT_ASC)
->limit(1));

if (empty($master)) {
return false;
} else if (!$this->user->simpleLogin($master['uid'])) {
return false;
}

};

}
}
}
}
<?php
class GitHubGit_Action extends Widget_Abstract_Contents implements Widget_Interface_Do
{

public function action()
{
/** get added files */

// GitHub webhooks
// https://help.github.com/articles/post-receive-hooks
$payload = ltrim(urldecode(file_get_contents('php://input')), 'payload=');
$data = json_decode($payload, true); //without `true`, json_decode will return object instead of array
$repository_url = $data['repository']['url'];
$commits = $data['commits'];
foreach ($commits as $commit) {
foreach ($commit['added'] as $added_file) {
$added_files[] = $added_file;
}
}


/** login */
$master = $this->db->fetchRow($this->db->select()->from('table.users')
->where('group = ?', 'administrator')
->order('uid', Typecho_Db::SORT_ASC)
->limit(1));

if (empty($master)) {
return false;
} else if (!$this->user->simpleLogin($master['uid'])) {
return false;
}

/** add article */
if (isset($added_files) && is_array($added_files)) {
foreach ($added_files as $added_file) {


$prepare_post = function ($to_post_file) use ($login, $repository_prefix) {
$input = array(
'do' => 'publish',
'allowComment' => $this->options->defaultAllowComment,
'allowPing' => $this->options->defaultAllowPing,
'allowFeed' => $this->options->defaultAllowFeed
);

list($slug) = explode('.', basename($added_file));
list($slug) = explode('.', basename($to_post_file));
$input['slug'] = $slug;

$post = $this->db->fetchRow($this->db->select()
Expand All @@ -123,16 +83,39 @@ public function action()
$input['cid'] = $post['cid'];
}
}

$url = $repository_prefix . '/master/' . $to_post_file;
$post_text = file_get_contents($url);
$post_text_array = Spyc::YAMLLoad($post_text);

$post_sections = preg_split('/^---$/m', $post_text, 2, PREG_SPLIT_NO_EMPTY);
if (sizeof($post_sections) == 2) {
$post_body = $post_sections[1];
} else {
$post_body = $post_sections[0];
}

$input['title'] = $post_text_array['title'] ?: pathinfo($to_post_file)['filename'];
$input['category'] = $post_text_array['category'] ?: 'default';
$input['tags'] = implode(',', explode(' ', $post_text_array['tags'])) ?: '';
$input['text'] = MarkdownExtraExtended::defaultTransform($post_body);

$input['category'] = 'default';
$input['title'] = pathinfo($added_file)['filename'];
$url = preg_replace('#https://#', 'https://raw.', $repository_url) . '/master/' . $added_file;
$input['text'] = file_get_contents($url);
return $input;
};

$post_to_typecho = function ($input) {
if ($input) {
// It seems that only the first added file get published.
$this->widget('Widget_Contents_Post_Edit', NULL, $input, false)->action();
}
};


}
}
if (isset($added_files) && is_array($added_files)) {
$login();
foreach ($added_files as $to_post_file) {
$post_to_typecho($prepare_post($to_post_file));
}
}
}
}
9 changes: 2 additions & 7 deletions GitHubGit/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static function activate()
}

Helper::addAction(github_git, 'GitHubGit_Action');
return _t('请在插件设置里设置 GitHub 的Git参数') . $error;
return _t('安装成功') . $error;
}

/**
Expand All @@ -51,12 +51,7 @@ public static function deactivate()
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
$basePath = new Typecho_Widget_Helper_Form_Element_Text('basePath', NULL, '/_posts',
_t('Git目录'), _t('填写需要监控的Git目录')); // 默认为Jekyll的_posts目录
$form->addInput($basePath->addRule('required', _t('必须填写数据库用户名')));
}
public static function config(Typecho_Widget_Helper_Form $form){}

/**
* 个人用户的配置面板
Expand Down
42 changes: 35 additions & 7 deletions GitHubGit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,42 @@ That is:
Usage
-----

- Add new posts in your git repository.
This plugin is roughly jekyll compatible.
You just need to do as you normally do in jekyll.

- Add a new post in the `_posts` directory of your git repository.
- Commit and push to GitHub.

Your new post will be published in typecho automatically.

Post format
-----------

Example:

```yaml
---
title: your blog title
tags: apple orange
categroy: life
---

Write you posts in *markdown*.
```

If you have used jekyll before, you will find this format familiar.

But there are some differencs:

- Only support markdown markup.
- No self defined field.
- No support for `layout`, `published` and `permalink`. (We will use filename as permalink slug.)
- `category` only allows one value, since Typecho only allows one.
- `tags` only support space-separated strings. YAML list is not supported.


Done. Your new post will be published in typecho automatically:
Bugs
----

- Use your file name as post title.
- Use your file content as post text.
- Under the default category (which you can change it later).
[#9](https://github.com/weakish/plugins/issues/9) `git add` multiple files to repostiory, then push. Only the first file will be published into typecho.

Note: if you want some format, you need to use html tags.
Markdown support may be added in future version.
Loading

0 comments on commit 03c579a

Please sign in to comment.