You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.0 KiB
179 lines
4.0 KiB
// Copyright © 2015-2017 Daniele Tricoli <eriol@mornie.org>. |
|
// All rights reserved. |
|
// Use of this source code is governed by a BSD-style |
|
// license that can be found in the LICENSE file. |
|
|
|
package main // import "eriol.xyz/piken" |
|
|
|
import ( |
|
"fmt" |
|
"os" |
|
"path" |
|
"strings" |
|
"time" |
|
|
|
"github.com/Sirupsen/logrus" |
|
"github.com/atotto/clipboard" |
|
"github.com/codegangsta/cli" |
|
|
|
"eriol.xyz/piken/format" |
|
"eriol.xyz/piken/sql" |
|
) |
|
|
|
const ( |
|
unicodeDataUrl = "http://www.unicode.org/Public/UNIDATA/UnicodeData.txt" |
|
pikenHome = ".piken" |
|
defaultDatabaseFile = "piken.sqlite3" |
|
defaultDataFile = "UnicodeData.txt" |
|
version = "0.2" |
|
) |
|
|
|
var ( |
|
baseDir = path.Join(getHome(), pikenHome) |
|
databaseFile = path.Join(baseDir, defaultDatabaseFile) |
|
dataFile = path.Join(baseDir, defaultDataFile) |
|
store sql.Store |
|
) |
|
|
|
func main() { |
|
|
|
app := cli.NewApp() |
|
app.Name = "piken" |
|
app.Version = version |
|
app.Author = "Daniele Tricoli" |
|
app.Email = "eriol@mornie.org" |
|
app.Usage = "unicode search tool backed by SQLite3" |
|
|
|
if _, err := os.Stat(baseDir); os.IsNotExist(err) { |
|
os.Mkdir(baseDir, 0755) |
|
} |
|
|
|
if err := store.Open(databaseFile); err != nil { |
|
logrus.Fatal(err) |
|
} |
|
defer store.Close() |
|
|
|
app.Commands = []cli.Command{ |
|
{ |
|
Name: "update", |
|
Usage: "Update unicode data", |
|
Action: func(c *cli.Context) { |
|
modifiedTime, err := checkLastModified(unicodeDataUrl) |
|
if err != nil { |
|
logrus.Fatal(err) |
|
} |
|
|
|
lastUpdate, err := store.GetLastUpdate(defaultDataFile) |
|
if err != nil { |
|
logrus.Fatal(err) |
|
} |
|
|
|
if lastUpdate.Before(modifiedTime) { |
|
download(unicodeDataUrl, dataFile) |
|
|
|
records, err := readCsvFile(dataFile) |
|
if err != nil { |
|
logrus.Fatal(err) |
|
} |
|
|
|
if err := store.DeleteUnicodeData(); err != nil { |
|
logrus.Fatal(err) |
|
} |
|
|
|
if err := store.LoadFromRecords(records); err != nil { |
|
logrus.Fatal(err) |
|
} |
|
|
|
if lastUpdate == time.Unix(0, 0) { |
|
if err := store.CreateLastUpdate(defaultDataFile, |
|
modifiedTime); err != nil { |
|
logrus.Fatal(err) |
|
} |
|
} else { |
|
if err := store.UpdateLastUpdate(defaultDataFile, |
|
modifiedTime); err != nil { |
|
logrus.Fatal(err) |
|
} |
|
|
|
} |
|
|
|
} else { |
|
logrus.Info("Already up to date.") |
|
} |
|
|
|
}, |
|
}, |
|
{ |
|
Name: "search", |
|
Aliases: []string{"s"}, |
|
Usage: "Search for unicode", |
|
Flags: []cli.Flag{ |
|
cli.BoolFlag{ |
|
Name: "copy, c", |
|
Usage: "copy glyph to clipboard", |
|
}, |
|
cli.BoolTFlag{ |
|
Name: "show-glyph", |
|
Usage: "show glyph (defaults to true, use --show-glyph=false to disable)", |
|
}, |
|
cli.StringFlag{ |
|
Name: "separator", |
|
Value: " -- ", |
|
Usage: "separator for unicode fields", |
|
}, |
|
cli.StringSliceFlag{ |
|
Name: "fields", |
|
Value: &cli.StringSlice{"CodePoint", "Name"}, |
|
Usage: "unicode fields", |
|
}, |
|
}, |
|
Action: func(c *cli.Context) { |
|
args := strings.Join(c.Args(), " ") |
|
rows, err := store.SearchUnicode(args) |
|
if err != nil { |
|
logrus.Fatal(err) |
|
} |
|
|
|
fields := c.StringSlice("fields") |
|
// StringSliceFlag default value can't be overridden for now: |
|
// https://github.com/codegangsta/cli/issues/160 |
|
if c.IsSet("fields") { |
|
fields = fields[2:] |
|
// TODO: validate fields |
|
} |
|
|
|
formatter := format.NewTextFormatter( |
|
fields, |
|
c.String("separator"), |
|
c.Bool("show-glyph")) |
|
|
|
if c.Bool("copy") && len(rows) > 1 { |
|
logrus.Warn("Copy to clipboard not allowed for multiple rows.") |
|
} |
|
|
|
for _, row := range rows { |
|
|
|
b, err := formatter.Format(&row) |
|
if err != nil { |
|
logrus.Fatal(err) |
|
} |
|
fmt.Println(b) |
|
|
|
// Copy to clipboard only when one row is returned by search. |
|
if c.Bool("copy") && len(rows) == 1 { |
|
glyph, err := format.CodePointToGlyph(row.CodePoint) |
|
if err != nil { |
|
logrus.Fatalf("Impossible to convert %s to glyph.", |
|
row.CodePoint) |
|
} |
|
if err := clipboard.WriteAll(glyph); err != nil { |
|
logrus.Fatalf("Copy to clipboard failed: %v", err) |
|
} |
|
} |
|
} |
|
}, |
|
}, |
|
} |
|
|
|
app.Run(os.Args) |
|
}
|
|
|