Merge branch 'release/v0.0.1'
This commit is contained in:
+52
@@ -0,0 +1,52 @@
|
||||
---
|
||||
kind: pipeline
|
||||
name: default
|
||||
type: docker
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
clone:
|
||||
image: reg.int.it2000.com.cn/devops/git
|
||||
tags: true
|
||||
skip_verify: true
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: reg.int.it2000.com.cn/library/golang:1.15.6-buster
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
environment:
|
||||
GO111MODULE: on
|
||||
GOPROXY: https://goproxy.io
|
||||
commands:
|
||||
- go build -o tele-recv-linux
|
||||
|
||||
- name: release
|
||||
image: plugins/gitea-release
|
||||
volumes:
|
||||
- name: certs
|
||||
path: /etc/ssl/certs
|
||||
settings:
|
||||
api_key: fe1e1a8dd77de7452a3f473984c7ac6fe6c5abaf
|
||||
base_url: https://gitea.int.it2000.com.cn
|
||||
title: 0.0.1
|
||||
files:
|
||||
- tele-recv-linux
|
||||
checksum:
|
||||
- sha256
|
||||
when:
|
||||
event: tag
|
||||
|
||||
volumes:
|
||||
- name: deps
|
||||
host:
|
||||
path: /opt/go
|
||||
- name: certs
|
||||
host:
|
||||
path: /etc/ssl/certs
|
||||
- name: docker
|
||||
host:
|
||||
path: /var/run/docker.sock
|
||||
@@ -0,0 +1,3 @@
|
||||
tty*
|
||||
telegram.db
|
||||
.idea
|
||||
Generated
-8
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/tele-recv.iml" filepath="$PROJECT_DIR$/.idea/tele-recv.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
Generated
-8
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
Generated
-44
@@ -1,44 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="ab419b68-984b-4661-bb9a-26bcba1547b3" name="Default Changelist" comment="" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="GOROOT" url="file:///usr/local/Cellar/go/1.15.5/libexec" />
|
||||
<component name="ProjectId" id="1lm7nLrR9364W3kc4Ropplb4iwV" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="go.import.settings.migrated" value="true" />
|
||||
<property name="go.sdk.automatically.set" value="true" />
|
||||
<property name="go.tried.to.enable.integration.vgo.integrator" value="true" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||
<property name="node.js.detected.package.eslint" value="true" />
|
||||
<property name="node.js.detected.package.tslint" value="true" />
|
||||
<property name="node.js.path.for.package.eslint" value="project" />
|
||||
<property name="node.js.path.for.package.tslint" value="project" />
|
||||
<property name="node.js.selected.package.eslint" value="(autodetect)" />
|
||||
<property name="node.js.selected.package.tslint" value="(autodetect)" />
|
||||
<property name="settings.editor.selected.configurable" value="terminal" />
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="VgoProject">
|
||||
<integration-enabled>true</integration-enabled>
|
||||
<environment>
|
||||
<map>
|
||||
<entry key="GOPROXY" value="https://goproxy.io" />
|
||||
</map>
|
||||
</environment>
|
||||
</component>
|
||||
</project>
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
Copyright © 2020 NAME HERE <EMAIL ADDRESS>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// readCmd represents the read command
|
||||
var readCmd = &cobra.Command{
|
||||
Use: "read",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("read called")
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(readCmd)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// readCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
// readCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
||||
|
||||
func read() {
|
||||
|
||||
}
|
||||
+12
-3
@@ -24,10 +24,16 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
cfgFile string
|
||||
device string
|
||||
cfgFile string
|
||||
device string
|
||||
baudrate int
|
||||
bytesize byte
|
||||
lograw bool
|
||||
|
||||
dbFile string
|
||||
dbInit bool
|
||||
|
||||
socketAddress string
|
||||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
rootCmd = &cobra.Command{
|
||||
@@ -83,12 +89,15 @@ func initConfig() {
|
||||
|
||||
viper.AutomaticEnv() // read in environment variables that match
|
||||
|
||||
|
||||
// If a config file is found, read it in.
|
||||
if err := viper.ReadInConfig(); err == nil {
|
||||
fmt.Println("Using config file:", viper.ConfigFileUsed())
|
||||
device = viper.GetString("serial.device")
|
||||
baudrate = viper.GetInt("serial.baudrate")
|
||||
bytesize = byte(viper.GetInt("serial.bytesize"))
|
||||
lograw = viper.GetBool("serial.lograw")
|
||||
dbFile = viper.GetString("sqlite.file")
|
||||
dbInit = viper.GetBool("sqlite.init")
|
||||
socketAddress = viper.GetString("socket.address")
|
||||
}
|
||||
}
|
||||
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
Copyright © 2020 NAME HERE <EMAIL ADDRESS>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"it2000.com.cn/tele-recv/utils"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// startCmd represents the start command
|
||||
var startCmd = &cobra.Command{
|
||||
Use: "start",
|
||||
Short: "start telegram receive service",
|
||||
Long: `open serial port
|
||||
start a tcp server for processing`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
start()
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(startCmd)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// startCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
// startCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
||||
|
||||
func start() {
|
||||
// Go signal notification works by sending `os.Signal`
|
||||
// values on a channel. We'll create a channel to
|
||||
// receive these notifications (we'll also make one to
|
||||
// notify us when the program can exit).
|
||||
sigs := make(chan os.Signal, 1)
|
||||
done := make(chan bool, 1)
|
||||
|
||||
// `signal.Notify` registers the given channel to
|
||||
// receive notifications of the specified signals.
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||
utils.ServerRunning = true
|
||||
|
||||
// This goroutine executes a blocking receive for
|
||||
// signals. When it gets one it'll print it out
|
||||
// and then notify the program that it can finish.
|
||||
go func() {
|
||||
sig := <-sigs
|
||||
fmt.Println()
|
||||
fmt.Println(sig)
|
||||
utils.ServerRunning = false
|
||||
utils.StopSocketServer()
|
||||
done <- true
|
||||
}()
|
||||
|
||||
// The program will wait here until it gets the
|
||||
// expected signal (as indicated by the goroutine
|
||||
// above sending a value on `done`) and then exit.
|
||||
fmt.Println("awaiting signal")
|
||||
_ = utils.InitDb(dbFile, dbInit)
|
||||
go utils.Listen(socketAddress)
|
||||
for utils.ServerRunning {
|
||||
if !utils.IsPortOpen() {
|
||||
log.Println("try to open port")
|
||||
err := utils.OpenPort(device, baudrate, bytesize)
|
||||
if err != nil {
|
||||
log.Fatal("error in open serial port ", err)
|
||||
}
|
||||
log.Println("starting read")
|
||||
}
|
||||
buffer, count := utils.ReadPort()
|
||||
if count > 0 {
|
||||
if lograw {
|
||||
log.Print(string(buffer))
|
||||
}
|
||||
utils.Append(buffer)
|
||||
}
|
||||
}
|
||||
<-done
|
||||
fmt.Println("exiting")
|
||||
|
||||
}
|
||||
+17
-16
@@ -16,32 +16,33 @@ limitations under the License.
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tarm/serial"
|
||||
"os"
|
||||
"it2000.com.cn/tele-recv/utils"
|
||||
"log"
|
||||
)
|
||||
|
||||
// testCmd represents the test command
|
||||
var testCmd = &cobra.Command{
|
||||
Use: "test",
|
||||
Short: "Test Config",
|
||||
Long: `Test config file.
|
||||
Test serial port`,
|
||||
Short: "Test running environment",
|
||||
Long: `loading config file
|
||||
Test serial port
|
||||
Test load sqlite database and init table`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("test called")
|
||||
fmt.Println("device :",device)
|
||||
c := &serial.Config{Name: device, Baud: baudrate, Size: bytesize}
|
||||
s, err := serial.OpenPort(c)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(c , "opened")
|
||||
_ = s.Close()
|
||||
test()
|
||||
},
|
||||
}
|
||||
|
||||
func test() {
|
||||
log.Println("Testing environment")
|
||||
_ = utils.OpenPort(device, baudrate, bytesize)
|
||||
|
||||
err := utils.InitDb(dbFile, dbInit)
|
||||
if err != nil {
|
||||
println("create database error ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(testCmd)
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
DbDriver = "sqlite3"
|
||||
TableCreate =`'''
|
||||
create table IF NOT EXISTS telegram (
|
||||
[tele_id] INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
[tele_recv_time] TIMESTAMP NOT NULL DEFAULT (datetime('now', 'localtime')),
|
||||
[tele_processed] int(1) NOT NULL DEFAULT 0,
|
||||
[tele_text] TEXT NOT NULL
|
||||
)
|
||||
'''
|
||||
`
|
||||
)
|
||||
var (
|
||||
db *sql.DB
|
||||
)
|
||||
|
||||
func getDb(file string, init bool) (*sql.DB, error) {
|
||||
log.Println("init database ", init)
|
||||
if init {
|
||||
log.Println("remove database file", file)
|
||||
os.Remove(file)
|
||||
}
|
||||
db, err := sql.Open(DbDriver, file)
|
||||
defer db.Close()
|
||||
if err != nil {
|
||||
log.Fatal("error in open database ", err)
|
||||
}
|
||||
_, err = db.Exec(TableCreate)
|
||||
if err != nil {
|
||||
log.Fatal("error in create telegram table", err)
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
@@ -5,6 +5,7 @@ go 1.15
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/magiconair/properties v1.8.4 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.5
|
||||
github.com/mitchellh/mapstructure v1.4.0 // indirect
|
||||
github.com/pelletier/go-toml v1.8.1 // indirect
|
||||
github.com/spf13/afero v1.5.1 // indirect
|
||||
|
||||
@@ -118,6 +118,8 @@ github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQS
|
||||
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ=
|
||||
github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
|
||||
@@ -2,7 +2,13 @@ serial:
|
||||
device: ttyS1
|
||||
baudrate: 9600
|
||||
bytesize: 7
|
||||
lograw: true
|
||||
|
||||
|
||||
sqlite:
|
||||
file: telegram.db
|
||||
init: true
|
||||
|
||||
|
||||
socket:
|
||||
address: 127.0.0.1:6000
|
||||
@@ -0,0 +1,48 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/tarm/serial"
|
||||
)
|
||||
|
||||
var (
|
||||
device string
|
||||
baudrate int
|
||||
bytesize byte
|
||||
port *serial.Port
|
||||
portOpened = false
|
||||
)
|
||||
|
||||
func OpenPort(device string, baudrate int, bytesize byte) error {
|
||||
log.Println("opening port device:", device, ", baudrate=", baudrate, ", bytesize=", bytesize)
|
||||
config := &serial.Config{Name: device, Baud: baudrate, Size: bytesize, ReadTimeout: time.Second * 1}
|
||||
var err error
|
||||
port, err = serial.OpenPort(config)
|
||||
if err != nil {
|
||||
log.Fatalln("error in open serial port ", err)
|
||||
return err
|
||||
}
|
||||
log.Println("opened port ", port)
|
||||
portOpened = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func ReadPort() ([]byte, int) {
|
||||
buffer := make([]byte, 256)
|
||||
if !ServerRunning {
|
||||
return buffer, 0
|
||||
}
|
||||
count, err := port.Read(buffer)
|
||||
if err != nil && err != io.EOF {
|
||||
log.Println("error in read port ", err)
|
||||
//TODO: 3 time fail try to
|
||||
}
|
||||
return buffer, count
|
||||
}
|
||||
|
||||
func IsPortOpen() bool {
|
||||
return portOpened
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
const ServerType = "tcp"
|
||||
|
||||
var ServerRunning = false
|
||||
var client net.Conn
|
||||
var server net.Listener
|
||||
var ClientReady = false
|
||||
|
||||
func Listen(address string) {
|
||||
var err error
|
||||
server, err = net.Listen(ServerType, address)
|
||||
if err != nil {
|
||||
log.Fatal("error in create server ", err)
|
||||
}
|
||||
defer server.Close()
|
||||
log.Println("listen on ", address)
|
||||
for ServerRunning {
|
||||
conn, err := server.Accept()
|
||||
if err != nil {
|
||||
ServerRunning = false
|
||||
log.Fatalln("error in create connection ", err)
|
||||
}
|
||||
if client == nil {
|
||||
client = conn
|
||||
ClientReady = false
|
||||
log.Println("client connected ", client.RemoteAddr())
|
||||
LoadUnprocessed()
|
||||
} else {
|
||||
log.Println("client already connected, close")
|
||||
client.Close()
|
||||
client = nil
|
||||
conn.Close()
|
||||
}
|
||||
if IsClientConnected() {
|
||||
connCheck()
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func WriteToClient(data string) error {
|
||||
_, err := client.Write([]byte(data + "\r\n"))
|
||||
if err != nil {
|
||||
log.Println("error in write data to client socket ", err)
|
||||
closeClient()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func connCheck() bool {
|
||||
_, err := client.Read(make([]byte, 0))
|
||||
if err != nil && err != io.EOF {
|
||||
// this connection is invalid
|
||||
log.Println("conn closed....", err)
|
||||
client = nil
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func IsClientConnected() bool {
|
||||
return client != nil
|
||||
}
|
||||
|
||||
func closeClient() {
|
||||
if client != nil {
|
||||
client.Close()
|
||||
client = nil
|
||||
}
|
||||
}
|
||||
|
||||
func StopSocketServer() {
|
||||
if IsClientConnected() {
|
||||
client.Close()
|
||||
}
|
||||
if server != nil {
|
||||
server.Close()
|
||||
}
|
||||
}
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
const (
|
||||
DbDriver = "sqlite3"
|
||||
TableCreate = `
|
||||
create table IF NOT EXISTS telegram (
|
||||
[tele_id] INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
[tele_recv_time] TIMESTAMP NOT NULL DEFAULT (datetime('now', 'localtime')),
|
||||
[tele_processed] int(1) NOT NULL DEFAULT 0,
|
||||
[tele_text] TEXT NOT NULL
|
||||
)
|
||||
`
|
||||
InsertNew = "insert into telegram (tele_text) values (?)"
|
||||
InsertOld = "insert into telegram (tele_text, tele_processed) values (?, 1)"
|
||||
|
||||
count = "select count(*) from telegram where tele_processed=0"
|
||||
load = "select tele_id, tele_text from telegram where tele_processed=0 Limit 100"
|
||||
update = "update telegram set tele_processed = 1 where tele_id=?"
|
||||
)
|
||||
|
||||
type telegram struct {
|
||||
id int64
|
||||
text string
|
||||
}
|
||||
|
||||
var (
|
||||
dbFile string
|
||||
initTable bool
|
||||
initialized bool
|
||||
isWriting bool
|
||||
)
|
||||
|
||||
func getDb() *sql.DB {
|
||||
//log.Println("init database ", initTable)
|
||||
if initTable && !initialized {
|
||||
log.Println("remove database file", dbFile)
|
||||
os.Remove(dbFile)
|
||||
}
|
||||
db, err := sql.Open(DbDriver, dbFile)
|
||||
if err != nil {
|
||||
log.Fatal("error in open database ", err)
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
func InitDb(file string, init bool) error {
|
||||
dbFile = file
|
||||
initTable = init
|
||||
var dbErr error
|
||||
db := getDb()
|
||||
defer db.Close()
|
||||
_, dbErr = db.Exec(TableCreate)
|
||||
checkDbErr(dbErr, "error in create table")
|
||||
log.Println("database ", db, " initialized")
|
||||
initialized = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func InsertTelegram(teleString string) {
|
||||
getWriteLock()
|
||||
db := getDb()
|
||||
defer db.Close()
|
||||
var insertSQL string
|
||||
if ClientReady && WriteToClient(teleString) == nil {
|
||||
insertSQL = InsertOld
|
||||
} else {
|
||||
insertSQL = InsertNew
|
||||
}
|
||||
stmt, _ := db.Prepare(insertSQL)
|
||||
|
||||
defer stmt.Close()
|
||||
result, err := stmt.Exec(teleString)
|
||||
id, _ := result.LastInsertId()
|
||||
checkDbErr(err, "error in insert telegram ")
|
||||
isWriting = false
|
||||
if insertSQL == InsertOld {
|
||||
log.Println("telegram processed ", id)
|
||||
} else {
|
||||
log.Println("telegram saved ", id)
|
||||
}
|
||||
}
|
||||
|
||||
func LoadUnprocessed() {
|
||||
log.Println("loading telegram")
|
||||
db := getDb()
|
||||
defer db.Close()
|
||||
for {
|
||||
telegrams := getTelegram(db)
|
||||
if len(telegrams) < 1 {
|
||||
break
|
||||
}
|
||||
for _, t := range telegrams {
|
||||
if WriteToClient(t.text) == nil {
|
||||
processed(db, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
ClientReady = true
|
||||
log.Println("client is ready for new telegram")
|
||||
}
|
||||
|
||||
func getTelegram(db *sql.DB) []telegram {
|
||||
var telegrams []telegram
|
||||
num := countTelegram()
|
||||
log.Println("unprocessed : ", num)
|
||||
if num < 1 {
|
||||
return telegrams
|
||||
}
|
||||
log.Println("try to load unprocessed telegram ", num)
|
||||
rows, err := db.Query(load)
|
||||
checkDbErr(err, "error in query telegram")
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var t telegram
|
||||
err := rows.Scan(&t.id, &t.text)
|
||||
checkDbErr(err, "error in scan telegram")
|
||||
telegrams = append(telegrams, t)
|
||||
}
|
||||
return telegrams
|
||||
}
|
||||
|
||||
func processed(db *sql.DB, t telegram) {
|
||||
getWriteLock()
|
||||
tx, err := db.Begin()
|
||||
checkDbErr(err, "error in begin update")
|
||||
stmt, err := db.Prepare(update)
|
||||
defer stmt.Close()
|
||||
checkDbErr(err, "error in create update statement")
|
||||
result, err := stmt.Exec(t.id)
|
||||
checkDbErr(err, "error in update telegram status")
|
||||
id, _ := result.RowsAffected()
|
||||
log.Println(t.id, " telegram update : ", id > 0)
|
||||
isWriting = false
|
||||
log.Println("release lock")
|
||||
tx.Commit()
|
||||
}
|
||||
|
||||
func countTelegram() int64 {
|
||||
db := getDb()
|
||||
var countErr error
|
||||
stmt, _ := db.Prepare(count)
|
||||
defer stmt.Close()
|
||||
var num int64
|
||||
countErr = stmt.QueryRow().Scan(&num)
|
||||
checkDbErr(countErr, "error in count telegram")
|
||||
return num
|
||||
}
|
||||
|
||||
func getWriteLock() {
|
||||
count := 0
|
||||
log.Println("write lock :", isWriting)
|
||||
for isWriting && count < 10 {
|
||||
log.Println("waiting for write ")
|
||||
time.Sleep(5 * time.Second)
|
||||
count++
|
||||
}
|
||||
if count >= 10 {
|
||||
log.Fatalln("database locked")
|
||||
}
|
||||
isWriting = true
|
||||
}
|
||||
|
||||
func checkDbErr(err error, msg string) {
|
||||
if err != nil {
|
||||
log.Fatalln(msg, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"log"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
EndTag = "NNNN"
|
||||
Expression = "(?s)ZCZC.*NNNN"
|
||||
)
|
||||
|
||||
var buffer []byte
|
||||
|
||||
func Append(data []byte) {
|
||||
buffer = append(buffer, data...)
|
||||
if buffer[len(buffer)-1] == '\r' {
|
||||
buffer = append(buffer, '\n')
|
||||
}
|
||||
check()
|
||||
}
|
||||
|
||||
func check() {
|
||||
teleString := string(buffer)
|
||||
if strings.Index(teleString, EndTag) > 0 {
|
||||
exp, _ := regexp.Compile(Expression)
|
||||
telegram := exp.FindString(string(buffer))
|
||||
|
||||
if len(telegram) > 0 {
|
||||
log.Println("telegram : ", telegram)
|
||||
buffer = nil
|
||||
InsertTelegram(telegram)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user