Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
PenguinCabinet committed Sep 27, 2024
0 parents commit 9238527
Show file tree
Hide file tree
Showing 41 changed files with 2,879 additions and 0 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
on:
workflow_dispatch:
push:

name: Test
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.22.6'
- name: Install pkg for wails
run: sudo apt-get install libwebkit2gtk-4.0-dev libgtk-3-dev -y
- name: Install wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: wails build
run: wails build
- name: Test
run: go test
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
build/bin
node_modules
frontend/dist
frontend/node_modules
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<div align="center">

# nikki-book

wailsで作られたシンプルな日記帳ソフトウェア

![img](img/img1.png)

<br>
<br>
</div>


## 特徴
* 起動すると、今日の日記入力画面が開くので、すぐに日記を書き始められる※1
* 画像ビューワーのように、日記を見返せる
* ローカルのディレクトリにテキストファイルを作っていくシンプルな構造なので、日記データを扱いやすい


※1 エクスプローラとメモ帳で同等のことを行うと、

1. 日記を保存しているディレクトリをエクスプローラで開く
2. その日の日記のテキストファイルを作り
3. そのテキストファイルをメモ帳で開く

という3ステップが必要になる。


## ⬇️ インストール
[リリース]()からダウンロードして、展開してください。

## 🔨 使い方

### 設定タブ
![img2](img/img2.png)
* 日記ディレクトリパス
* 右上の選択ボタンを押すと、ダイアログが開き、簡単にディレクトリを選択できます
* 日記ファイルフォーマット
* YYYYはその日の年度が入ります
* MMはその日のゼロ詰めの月が入ります
* DDはその日のゼロ詰めの日が入ります

**設定変更はソフトウェア再起動で反映されます。**

### 日記タブ
![img1](img/img1.png)

「←」ボタンで一つ前の日記へ、「→」ボタンで次の日記へ進みます。
「Today」ボタンで今日の日記に飛びます。
変更した内容は日記ディレクトリのテキスファイルに自動保存されます。

### 日記ディレクトリの構成
[日記ディレクトリの例](./test-dir/)
```text
2024年09月18日.txt
2024年09月19日.txt
```
日記の月日はすべて、ゼロ詰めです。
ソフトウェア起動時に、今日の日記テキストファイルがない場合、自動的に作成されます。

## 🎫 LICENSE

[MIT](./LICENSE)

## ✍ Author

[PenguinCabinet](https://github.com/PenguinCabinet)
221 changes: 221 additions & 0 deletions app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
package main

import (
"context"
"encoding/json"
"io/ioutil"
"os"
"path"
"path/filepath"
"sort"
"strings"
"time"

"github.com/wailsapp/wails/v2/pkg/runtime"
)

type Nikki_date_t struct {
Year int
Month int
Day int
}

type Nikki_t struct {
Fname string
Date Nikki_date_t
Content string
}

type Setting_t struct {
Nikki_dir string
Fname_format string
}

var default_Setting_data = Setting_t{Nikki_dir: "", Fname_format: "YYYY年MM月DD日.txt"}

// App struct
type App struct {
ctx context.Context
Nikki_data []Nikki_t
Setting_data Setting_t
setting_json_path string
}

// NewApp creates a new App application struct
func NewApp() *App {
app := &App{}
app.Setting_data = default_Setting_data
exe_path, err := os.Executable()
if err != nil {
panic(err)
}
app.setting_json_path = path.Join(filepath.Dir(exe_path), "nikki-book-setting.json")

return app
}

func TimeFormat_conv(v string) string {
reslut := v
reslut = strings.Replace(reslut, "YYYY", "2006", 1)
reslut = strings.Replace(reslut, "MM", "01", 1)
reslut = strings.Replace(reslut, "DD", "02", 1)
return reslut
}

// startup is called when the app starts. The context is saved
// so we can call the runtime methods
func (a *App) startup(ctx context.Context) {
a.ctx = ctx
}

func (a *App) Get_dir_fnames(dir_name string) []string {
dir_data, err := ioutil.ReadDir(dir_name)
if err != nil {
return []string{}
}

var fnames []string
for _, e := range dir_data {
fnames = append(fnames, e.Name())
}

return fnames
}

func (a *App) Add_nikki_today() {
if a.Setting_data.Nikki_dir == "" {
return
}

timezone := time.FixedZone("Asia/Tokyo", 9*60*60)
time_now := time.Now().In(timezone)
f, err := os.OpenFile(
path.Join(
a.Setting_data.Nikki_dir,
time_now.Format(TimeFormat_conv(a.Setting_data.Fname_format)),
),
os.O_WRONLY|os.O_CREATE, 0666,
)
if err != nil {
}
f.Close()
}

func (a *App) Parse_nikki_file(fname string) Nikki_t {
content, err := ioutil.ReadFile(path.Join(a.Setting_data.Nikki_dir, fname))
if err != nil {
panic(err)
}

Fname_format_golang := TimeFormat_conv(a.Setting_data.Fname_format)

t, err := time.Parse(Fname_format_golang, fname)

return Nikki_t{
Fname: fname, Content: string(content),
Date: Nikki_date_t{
Year: t.Year(),
Month: int(t.Month()),
Day: t.Day(),
},
}
}

func (a *App) Write_nikki_file(v Nikki_t) {
var err error
var f *os.File
f, err = os.Create(path.Join(a.Setting_data.Nikki_dir, v.Fname))
for err != nil {
f, err = os.Create(path.Join(a.Setting_data.Nikki_dir, v.Fname))
time.Sleep(time.Millisecond * 200)
}
defer f.Close()

_, err = f.Write([]byte(v.Content))
if err != nil {
panic(err)
}
}

func (a *App) Set_nikki(v []Nikki_t) {
for i, e := range v {
if a.Nikki_data[i].Content != e.Content {
a.Nikki_data[i].Content = e.Content
a.Write_nikki_file(a.Nikki_data[i])
}
}

}

func (a *App) Load_nikki() {
var reslut []Nikki_t
for _, e := range a.Get_dir_fnames(a.Setting_data.Nikki_dir) {
reslut = append(reslut, a.Parse_nikki_file(e))
}

sort.SliceStable(reslut, func(i, j int) bool {
if reslut[i].Date.Year != reslut[j].Date.Year {
return reslut[i].Date.Year > reslut[j].Date.Year
}
if reslut[i].Date.Month != reslut[j].Date.Month {
return reslut[i].Date.Month > reslut[j].Date.Month
}
return reslut[i].Date.Day > reslut[j].Date.Day
})
a.Nikki_data = reslut
}

func (a *App) Get_nikki() []Nikki_t {

return a.Nikki_data
}

func (a *App) Load_setting() {

setting_text, err := ioutil.ReadFile(a.setting_json_path)
if err == nil {
if err := json.Unmarshal(setting_text, &a.Setting_data); err != nil {
a.Setting_data = default_Setting_data
}
} else {
a.Setting_data = default_Setting_data
}

}

func (a *App) Write_setting() {
setting_text, err := json.Marshal(a.Setting_data)
f, err := os.Create(a.setting_json_path)
for err != nil {
f, err = os.Create(a.setting_json_path)
time.Sleep(time.Millisecond * 200)
}
defer f.Close()

_, err = f.Write([]byte(setting_text))
if err != nil {
panic(err)
}
}

func (a *App) Get_setting() Setting_t {
return a.Setting_data
}

func (a *App) Set_setting(v Setting_t) {
if a.Setting_data != v {
a.Setting_data = v
a.Write_setting()
}
}

func (a *App) Select_Nikki_dir_Dialog() string {
path_data, err := runtime.OpenDirectoryDialog(a.ctx, runtime.OpenDialogOptions{
DefaultDirectory: "",
Title: "日記を保存するディレクトリを選択してください",
})
if err != nil {
return ""
}
return path_data
}
39 changes: 39 additions & 0 deletions app_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestGet_dir_files(t *testing.T) {
app := App{}
assert.Equal(t, []string{"2024年09月18日.txt", "2024年09月19日.txt"}, app.Get_dir_fnames("test-dir"))
}

func TestTimeFormat_conv(t *testing.T) {
time1, err := time.Parse("2006-01-02", "2024-09-19")
assert.NoError(t, err)
assert.Equal(t, 2024, time1.Year())
assert.Equal(t, 9, int(time1.Month()))
assert.Equal(t, 19, time1.Day())

time2, err := time.Parse("2006年01月02日", "2024年09月19日")
assert.NoError(t, err)
assert.Equal(t, 2024, time2.Year())
assert.Equal(t, 9, int(time2.Month()))
assert.Equal(t, 19, time2.Day())

assert.Equal(t, "2006年01月02日.txt", TimeFormat_conv("YYYY年MM月DD日.txt"))
}

func TestParse_nikki_file(t *testing.T) {
app := App{}
app.Setting_data.Nikki_dir = "test-dir"
app.Setting_data.Fname_format = "YYYY年MM月DD日.txt"

assert.EqualExportedValues(t,
Nikki_t{Fname: "2024年09月19日.txt", Date: Nikki_date_t{Year: 2024, Month: 9, Day: 19}, Content: "Test!"},
app.Parse_nikki_file("2024年09月19日.txt"))
}
35 changes: 35 additions & 0 deletions build/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Build Directory

The build directory is used to house all the build files and assets for your application.

The structure is:

* bin - Output directory
* darwin - macOS specific files
* windows - Windows specific files

## Mac

The `darwin` directory holds files specific to Mac builds.
These may be customised and used as part of the build. To return these files to the default state, simply delete them
and
build with `wails build`.

The directory contains the following files:

- `Info.plist` - the main plist file used for Mac builds. It is used when building using `wails build`.
- `Info.dev.plist` - same as the main plist file but used when building using `wails dev`.

## Windows

The `windows` directory contains the manifest and rc files used when building with `wails build`.
These may be customised for your application. To return these files to the default state, simply delete them and
build with `wails build`.

- `icon.ico` - The icon used for the application. This is used when building using `wails build`. If you wish to
use a different icon, simply replace this file with your own. If it is missing, a new `icon.ico` file
will be created using the `appicon.png` file in the build directory.
- `installer/*` - The files used to create the Windows installer. These are used when building using `wails build`.
- `info.json` - Application details used for Windows builds. The data here will be used by the Windows installer,
as well as the application itself (right click the exe -> properties -> details)
- `wails.exe.manifest` - The main application manifest file.
Binary file added build/appicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added build/appicon_te.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 9238527

Please sign in to comment.