This commit is contained in:
Denis Zheleztsov 2019-03-14 18:42:15 +03:00
commit c71af3e046
Signed by: Difrex
GPG Key ID: B047A0E62A285621
13 changed files with 456 additions and 0 deletions

14
cmd/args.go Normal file
View File

@ -0,0 +1,14 @@
package main
import (
"flag"
)
var (
filePath string
)
func init() {
flag.StringVar(&filePath, "config", "config.json", "Path to the configuration file")
flag.Parse()
}

27
cmd/config.go Normal file
View File

@ -0,0 +1,27 @@
package main
import (
"io/ioutil"
"log"
"encoding/json"
"github.com/idec-net/github2idec/g2i"
)
// loadConfig loads bot configuration from file
func loadConfig(path string) *g2i.Config {
log.Print("Loading configuration")
config := &g2i.Config{}
data, err := ioutil.ReadFile(path)
if err != nil {
panic(err)
}
err = json.Unmarshal(data, config)
if err != nil {
panic(err)
}
return config
}

71
cmd/main.go Normal file
View File

@ -0,0 +1,71 @@
package main
import (
"context"
"fmt"
"os"
"text/template"
"github.com/google/go-github/github"
"github.com/idec-net/github2idec/g2i"
)
func main() {
ctx := context.Background()
config := loadConfig(filePath)
gClient := g2i.NewGithubClient(config, ctx)
eventsURL, err := gClient.EventsURL()
if err != nil {
panic(err)
}
fmt.Println(eventsURL)
// events, err := gClient.GetEvents(eventsURL)
// if err != nil {
// panic(err)
// }
issues, err := gClient.GetIssues()
if err != nil {
panic(err)
}
helloMessage := struct {
Sources, Name, Owner, Repo string
Issues []*github.Issue
}{
Sources: "https://github.com/idec-net/github2idec",
Name: "Gdec",
Owner: config.Github.RepoOwner,
Repo: config.Github.Repo,
Issues: issues,
}
t, err := template.New("hello_message.tpl").
ParseFiles("../templates/hello_message.tpl")
if err != nil {
panic(err)
}
err = t.Execute(os.Stdout, helloMessage)
if err != nil {
panic(err)
}
// for _, event := range events {
// if config.IsEventProcessable(*event.Type) {
// b, err := event.RawPayload.MarshalJSON()
// if err != nil {
// panic(err)
// }
// var comment g2i.GithubIssueComment
// err = json.Unmarshal(b, &comment)
// if err != nil {
// panic(err)
// }
// fmt.Printf("===============\nAuthor: %s\n", comment.Comment.User.Login)
// fmt.Printf("Issue: %s\nUrl: %s\n", comment.Issue.Title, comment.Comment.URL)
// fmt.Printf("CreatedAt: %s\n", comment.Comment.CreatedAt.Format("2006 Jan 2 15:04:05 UTC"))
// fmt.Printf("%s\n===============\n\n", comment.Comment.Body)
// }
// }
}

27
config/config.sample.json Normal file
View File

@ -0,0 +1,27 @@
{
"data": {
"path": "./data"
},
"idec": {
"fetch": {
"echoes": [
"idec.talks"
],
"limit": 25,
"offset": -25
},
"authstring": "",
"node_url": "https://dynamic.lessmore.pw/idec/",
"hello_message": true,
"hello_message_template_path": "../templates/hello_message.tpl",
"top_post_id": "hOxZjLmgYv3Qwb32vJIK"
},
"github": {
"repo_owner": "idec-net",
"repo": "netmail",
"token": "",
"watched_event_types": [
"IssueCommentEvent"
]
}
}

16
g2i/client.go Normal file
View File

@ -0,0 +1,16 @@
package g2i
import (
"context"
)
type Client struct {
GHClient *GithubClient
IDECClient *IDECClient
}
func (c *Config) NewClient(ctx context.Context) (*Client, error) {
client := &Client{}
ghc := NewGithubClient(c, ctx)
return client, nil
}

33
g2i/config.go Normal file
View File

@ -0,0 +1,33 @@
package g2i
type Config struct {
Data Data `json:"data"`
IDEC IDEC `json:"idec"`
Github Github `json:"github"`
}
type Data struct {
Path string `json:"path"`
}
type Fetch struct {
Echoes []string `json:"echoes"`
Limit int `json:"limit"`
Offset int `json:"offset"`
}
type IDEC struct {
Fetch Fetch `json:"fetch"`
Authstring string `json:"authstring"`
NodeURL string `json:"node_url"`
HelloMessage bool `json:"hello_message"`
HelloMessageTemplatePath string `json:"hello_message_template_path"`
TopPostID string `json:"top_post_id"`
}
type Github struct {
RepoOwner string `json:"repo_owner"`
Repo string `json:"repo"`
Token string `json:"token"`
WatchedEventTypes []string `json:"watched_event_types"`
}

88
g2i/ghcomments.go Normal file
View File

@ -0,0 +1,88 @@
package g2i
import (
"time"
)
type GithubIssueComment struct {
Action string `json:"action"`
Issue Issue `json:"issue"`
Comment Comment `json:"comment"`
}
type User struct {
Login string `json:"login"`
ID int `json:"id"`
NodeID string `json:"node_id"`
AvatarURL string `json:"avatar_url"`
GravatarID string `json:"gravatar_id"`
URL string `json:"url"`
HTMLURL string `json:"html_url"`
FollowersURL string `json:"followers_url"`
FollowingURL string `json:"following_url"`
GistsURL string `json:"gists_url"`
StarredURL string `json:"starred_url"`
SubscriptionsURL string `json:"subscriptions_url"`
OrganizationsURL string `json:"organizations_url"`
ReposURL string `json:"repos_url"`
EventsURL string `json:"events_url"`
ReceivedEventsURL string `json:"received_events_url"`
Type string `json:"type"`
SiteAdmin bool `json:"site_admin"`
}
type Labels struct {
ID int `json:"id"`
NodeID string `json:"node_id"`
URL string `json:"url"`
Name string `json:"name"`
Color string `json:"color"`
Default bool `json:"default"`
}
type PullRequest struct {
URL string `json:"url"`
HTMLURL string `json:"html_url"`
DiffURL string `json:"diff_url"`
PatchURL string `json:"patch_url"`
}
type Issue struct {
URL string `json:"url"`
RepositoryURL string `json:"repository_url"`
LabelsURL string `json:"labels_url"`
CommentsURL string `json:"comments_url"`
EventsURL string `json:"events_url"`
HTMLURL string `json:"html_url"`
ID int `json:"id"`
NodeID string `json:"node_id"`
Number int `json:"number"`
Title string `json:"title"`
User User `json:"user"`
Labels []Labels `json:"labels"`
State string `json:"state"`
Locked bool `json:"locked"`
Assignee interface{} `json:"assignee"`
Assignees []interface{} `json:"assignees"`
Milestone interface{} `json:"milestone"`
Comments int `json:"comments"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ClosedAt interface{} `json:"closed_at"`
AuthorAssociation string `json:"author_association"`
PullRequest PullRequest `json:"pull_request"`
Body string `json:"body"`
}
type Comment struct {
URL string `json:"url"`
HTMLURL string `json:"html_url"`
IssueURL string `json:"issue_url"`
ID int `json:"id"`
NodeID string `json:"node_id"`
User User `json:"user"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
AuthorAssociation string `json:"author_association"`
Body string `json:"body"`
}

83
g2i/github.go Normal file
View File

@ -0,0 +1,83 @@
package g2i
import (
"context"
"log"
"encoding/json"
"net/http"
"github.com/google/go-github/github"
)
type GithubClient struct {
c *github.Client
Owner string
Repo string
token string
ctx context.Context
}
func NewGithubClient(config *Config, ctx context.Context) *GithubClient {
if config.Github.Token != "" {
}
client := github.NewClient(nil)
return &GithubClient{client, config.Github.RepoOwner, config.Github.Repo, config.Github.Token, ctx}
}
// GetIssues returns all repo issues
func (g *GithubClient) GetIssues() ([]*github.Issue, error) {
log.Print("Get repository issues")
issues, _, err := g.c.Issues.ListByRepo(g.ctx, g.Owner, g.Repo, nil)
return issues, err
}
// GetRepoEvents
func (g *GithubClient) EventsURL() (string, error) {
var eventsURL string
repos, _, err := g.c.Repositories.ListByOrg(g.ctx, g.Owner, nil)
if err != nil {
return eventsURL, err
}
for i, _ := range repos {
if *repos[i].Name == g.Repo {
eventsURL = *repos[i].EventsURL
break
}
}
return eventsURL, nil
}
// GetEvents returns repo events
func (g *GithubClient) GetEvents(eventsURL string) ([]github.Event, error) {
var events []github.Event
client := &http.Client{}
req, err := http.NewRequest("GET", eventsURL, nil)
if err != nil {
return events, err
}
resp, err := client.Do(req)
if err != nil {
return events, err
}
defer resp.Body.Close()
err = json.NewDecoder(resp.Body).Decode(&events)
if err != nil {
return events, err
}
return events, nil
}
func (c *Config) IsEventProcessable(eventType string) bool {
for i, _ := range c.Github.WatchedEventTypes {
if eventType == c.Github.WatchedEventTypes[i] {
return true
}
}
return false
}

9
g2i/go.mod Normal file
View File

@ -0,0 +1,9 @@
module github.com/idec-net/github2idec/g2i
go 1.12
require (
github.com/Difrex/go-idec v0.0.0-20170724073226-420b1f419842
github.com/google/go-github v17.0.0+incompatible
github.com/google/go-github/v24 v24.0.1 // indirect
)

14
g2i/go.sum Normal file
View File

@ -0,0 +1,14 @@
github.com/Difrex/go-idec v0.0.0-20170724073226-420b1f419842 h1:xrw8RxKPECWc+8vxDaMFwiNGlYngXRcRB3QwTlOIHYg=
github.com/Difrex/go-idec v0.0.0-20170724073226-420b1f419842/go.mod h1:Krw/MoqqCqbZg0cRMw2FAU2JLifGYbw+iNK5FRYrCFs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-github/v24 v24.0.1 h1:KCt1LjMJEey1qvPXxa9SjaWxwTsCWSq6p2Ju57UR4Q4=
github.com/google/go-github/v24 v24.0.1/go.mod h1:CRqaW1Uns1TCkP0wqTpxYyRxRjxwvKU/XSS44u6X74M=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=

14
g2i/helpers.go Normal file
View File

@ -0,0 +1,14 @@
package g2i
import (
"io"
"text/template"
)
func (c *Config) generateTemplate(name, path string, data interface{}, wr io.Writer) error {
t, err := template.New(name).ParseFiles(c.IDEC.HelloMessageTemplatePath)
if err != nil {
return err
}
return t.Execute(wr, data)
}

47
g2i/idec.go Normal file
View File

@ -0,0 +1,47 @@
package g2i
import (
"log"
"strings"
"bytes"
idec "github.com/Difrex/go-idec"
"github.com/google/go-github/github"
)
type IDECClient struct {
FetchConfig *idec.FetchConfig
config *Config
}
func NewIDECClient(config *Config) *IDECClient {
return &IDECClient{
config: config,
FetchConfig: &idec.FetchConfig{
Limit: config.IDEC.Fetch.Limit,
Offset: config.IDEC.Fetch.Offset,
Node: config.IDEC.NodeURL,
Echoes: config.IDEC.Fetch.Echoes,
},
}
}
type HelloMessage struct {
Sources, Name, Owner, Repo string
Issues []*github.Issue
}
func (i *IDECClient) PostHello() {
pointURL := strings.TrimRight(i.FetchConfig.Node, "/") + "/u/point"
message := idec.PointMessage{}
body := &bytes.Buffer{}
err := i.config.generateTemplate("hello_message.tpl", i.config.IDEC.HelloMessageTemplatePath, i.FetchConfig, body)
if err != nil {
log.Print("Error", err.Error())
}
message.Body = body.String()
log.Print(message, pointURL)
}

View File

@ -0,0 +1,13 @@
Привет!
Это первое сообщение от {{.Name}} - бота слежения за задачами в репозитории на Github.
Сейчас я наблюдаю за проектом {{.Owner}}/{{.Repo}}.
Текущие открытые задачи:
{{range $i, $issue := .Issues}}
* {{$issue.Title}} {{$issue.URL}}
{{end}}
Новые события будут публиковаться в этой теме.
+++ {{.Name}}: {{.Sources}}. GPLv3