Compare commits

...

42 Commits
v0.7 ... master

Author SHA1 Message Date
Bel LaPointe f0f4b14310 gogs.inhome mods 2023-04-10 11:16:19 -06:00
Bel LaPointe 62dc4fa565 Merge branch 'master' of https://gogs.inhome.blapointe.com/local/todo-server 2023-04-10 11:15:20 -06:00
Bel LaPointe 651ff0e04d white space 2021-10-04 13:34:41 -06:00
Bel LaPointe 078674a06f fatter task action button, fix weird spacing 2021-09-17 09:43:13 -06:00
Bel LaPointe 0ae0609759 remove unused jq file, return false on form to avoid reload 2021-09-17 09:04:28 -06:00
Bel LaPointe f67f3dd8a1 Upgrade to 1-6-5-UI and images 2021-09-17 08:53:35 -06:00
Bel LaPointe a121503777 gitignore v1.6.5 2021-09-17 08:26:36 -06:00
Bel LaPointe 28b0110e2d go.mod 2021-09-17 08:24:59 -06:00
bel f5e3a6e867 shrink 2021-09-08 14:25:43 -06:00
bel 734fe9d286 shrink 2021-09-08 14:25:43 -06:00
Bel LaPointe 80b058a869 set looped task to latest idx 2021-08-30 09:37:40 -06:00
Bel LaPointe 01adec7db5 set looped task to latest idx 2021-08-30 09:37:40 -06:00
Bel LaPointe 2bca997483 support only looping 2021-08-17 11:47:10 -06:00
Bel LaPointe 95b10fd9f6 support only looping 2021-08-17 11:47:10 -06:00
bel 568aa6a229 haflways 2021-08-05 23:45:11 -06:00
bel fc088ec240 haflways 2021-08-05 23:45:11 -06:00
bel 435ff82683 either of cron or loop can be set and unset, mark invalids as invalid and unfinish 2021-07-17 23:58:51 -06:00
bel 2763b68bc4 either of cron or loop can be set and unset, mark invalids as invalid and unfinish 2021-07-17 23:58:51 -06:00
bel 327fdb925c add cron to loop 2021-07-17 23:35:24 -06:00
bel f84614a8da add cron to loop 2021-07-17 23:35:24 -06:00
bel 5e70a49c2c add cron to ui 2021-07-17 23:17:09 -06:00
bel c2ed541604 add cron to ui 2021-07-17 23:17:09 -06:00
bel 0f8637c9ff async triggers for either interval or next due, accept cron 2021-07-17 23:14:54 -06:00
bel 8c7fe2e9ef async triggers for either interval or next due, accept cron 2021-07-17 23:14:54 -06:00
bel c90cbfc7be support combo new and old 2021-07-17 22:51:54 -06:00
bel 9301ddd467 support combo new and old 2021-07-17 22:51:54 -06:00
bel 8a47f5f321 support 1w, 1d for loop 2021-07-17 22:49:10 -06:00
bel d5ec073f75 support 1w, 1d for loop 2021-07-17 22:49:10 -06:00
Bel LaPointe b8f0efc01c every -loop duration, look for completed tasks with loop set and incomplete them 2021-07-17 11:04:52 -06:00
Bel LaPointe 81c8743de7 accept loop param on task 2021-07-17 10:34:22 -06:00
Bel LaPointe 6abfab229a log 2021-04-20 07:55:49 -05:00
Bel LaPointe ec780f7d9b actually do handler 2021-04-20 07:54:33 -05:00
Bel LaPointe 94a14f8b9d set content type 2021-04-20 07:40:13 -05:00
Bel LaPointe 90dbfd6f5a gr 2021-04-20 07:32:46 -05:00
Bel LaPointe de5f17e2c9 impl oauth 2021-04-20 07:04:05 -05:00
Bel LaPointe 0e22586e12 fix method 2021-04-20 06:27:57 -05:00
Bel LaPointe 80becbb7a7 weird paths just redir to root 2021-04-20 06:09:02 -05:00
bel 2e98bdff2d Oh hey html has a solution for my css bullshit 2020-03-17 03:28:39 +00:00
bel 8f966c98a4 whoops on css 2020-03-12 04:41:31 +00:00
bel a0f336ca67 CSS but not lighter for mobile 2020-03-12 04:36:36 +00:00
bel f8b5eb71e0 remove unused param 2020-03-12 00:57:58 +00:00
bel 7c70ba27cb fix multi-line task note preview 2020-02-02 06:13:27 +00:00
54 changed files with 1396 additions and 962 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ todo-server
exec-todo-server
notes-server
exec-notes-server
testdata/mytinytodo-v1.6.5*

View File

@ -2,19 +2,21 @@ package config
import (
"fmt"
"local/args"
"gogs.inhome.blapointe.com/local/args"
"os"
"strings"
"time"
)
var (
Port string
StoreType string
StoreAddr string
StoreUser string
StorePass string
Root string
MyTinyTodo string
Port string
StoreType string
StoreAddr string
StoreUser string
StorePass string
Root string
OAuth string
Loop time.Duration
)
func init() {
@ -32,8 +34,9 @@ func Refresh() {
as.Append(args.STRING, "storeaddr", "addr of store", "")
as.Append(args.STRING, "storeuser", "user of store", "")
as.Append(args.STRING, "storepass", "pass of store", "")
as.Append(args.STRING, "mtt", "url of php server", "http://localhost:38808")
as.Append(args.STRING, "oauth", "url for boauthz", "")
as.Append(args.STRING, "root", "root of static files", "./public")
as.Append(args.DURATION, "loop", "loop duration for refreshing completed tasks", time.Minute)
if err := as.Parse(); err != nil {
panic(err)
}
@ -44,5 +47,6 @@ func Refresh() {
StoreUser = as.Get("storeuser").GetString()
StorePass = as.Get("storepass").GetString()
Root = as.Get("root").GetString()
MyTinyTodo = as.Get("mtt").GetString()
Loop = as.Get("loop").GetDuration()
OAuth = as.Get("oauth").GetString()
}

13
go.mod Normal file
View File

@ -0,0 +1,13 @@
module gogs.inhome.blapointe.com/local/todo-server
go 1.16
require (
github.com/google/uuid v1.3.0
github.com/robfig/cron/v3 v3.0.1
gogs.inhome.blapointe.com/local/args v0.0.0-20230410154220-44370f257b34
gogs.inhome.blapointe.com/local/gziphttp v0.0.0-20230410171240-32da87640b26
gogs.inhome.blapointe.com/local/oauth2 v0.0.0-20230410162733-d39498ff8454
gogs.inhome.blapointe.com/local/router v0.0.0-20230410162418-08ccdc13df87
gogs.inhome.blapointe.com/local/storage v0.0.0-20230410162102-db39d7b02e29
)

269
go.sum Normal file
View File

@ -0,0 +1,269 @@
bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
cloud.google.com/go v0.33.1 h1:fmJQWZ1w9PGkHR1YL/P7HloDvqlmKQ4Vpb7PC2e+aCk=
cloud.google.com/go v0.33.1/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
github.com/Azure/azure-storage-blob-go v0.0.0-20181023070848-cf01652132cc/go.mod h1:oGfmITT1V6x//CswqY2gtAHND+xIP64/qL7a5QJix0Y=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Unknwon/goconfig v0.0.0-20181105214110-56bd8ab18619 h1:6X8iB881g299aNEv6KXrcjL31iLOH7yA6NXoQX+MbDg=
github.com/Unknwon/goconfig v0.0.0-20181105214110-56bd8ab18619/go.mod h1:wngxua9XCNjvHjDiTiV26DaKDT+0c63QR6H5hjVUUxw=
github.com/a8m/tree v0.0.0-20180321023834-3cf936ce15d6/go.mod h1:FSdwKX97koS5efgm8WevNf7XS3PqtyFkKDDXrz778cg=
github.com/abbot/go-http-auth v0.4.0 h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0=
github.com/abbot/go-http-auth v0.4.0/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM=
github.com/anacrolix/dms v0.0.0-20180117034613-8af4925bffb5/go.mod h1:DGqLjaZ3ziKKNRt+U5Q9PLWJ52Q/4rxfaaH/b3QYKaE=
github.com/aws/aws-sdk-go v1.15.81 h1:va7uoFaV9uKAtZ6BTmp1u7paoMsizYRRLvRuoC07nQ8=
github.com/aws/aws-sdk-go v1.15.81/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
github.com/billziss-gh/cgofuse v1.1.0/go.mod h1:LJjoaUojlVjgo5GQoEJTcJNqZJeRU0nCR84CyxKt2YM=
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/coreos/bbolt v0.0.0-20180318001526-af9db2027c98/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/cpuguy83/go-md2man v1.0.8/go.mod h1:N6JayAiVKtlHSnuTCeuLSQVs75hb8q+dYQLjr7cDsKY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/djherbis/times v1.1.0/go.mod h1:CGMZlo255K5r4Yw0b9RRfFQpM2y7uOmxg4jm9HsaVf8=
github.com/dropbox/dropbox-sdk-go-unofficial v5.4.0+incompatible/go.mod h1:lr+LhMM3F6Y3lW1T9j2U5l7QeuWm87N9+PPXo3yH4qY=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9/go.mod h1:GpOj6zuVBG3Inr9qjEnuVTgBlk2lZ1S9DcoFiXWyKss=
github.com/goftp/server v0.0.0-20190111142836-88de73f463af/go.mod h1:k/SS6VWkxY7dHPhoMQ8IdRu8L4lQtmGbhyXGg+vCnXE=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.8.5 h1:nRAxCa+SVsyjSBrtZmG/cqb6VbTmuRzpg/PoTFlpumc=
github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jlaffaye/ftp v0.0.0-20181101112434-47f21d10f0ee/go.mod h1:lli8NYPQOFy3O++YmYbqVgOcQ1JPCwdOy+5zSjKJ9qY=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M=
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v1.2.3 h1:CCtW0xUnWGVINKvE/WWOYKdsPV6mawAtvQuSl8guwQs=
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
github.com/minio/minio-go/v6 v6.0.57 h1:ixPkbKkyD7IhnluRgQpGSpHdpvNVaW6OD5R9IAO/9Tw=
github.com/minio/minio-go/v6 v6.0.57/go.mod h1:5+R/nM9Pwrh0vqF+HbYYDQ84wdUFPyXHkrdT4AIkifM=
github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2/go.mod h1:MLIrzg7gp/kzVBxRE1olT7CWYMCklcUWU+ekoxOD9x0=
github.com/ncw/rclone v1.46.0 h1:5SY9lB6LIIXqwOaCWp5twUqNWgJVZMW+0D4rX90A2+E=
github.com/ncw/rclone v1.46.0/go.mod h1:+uFY4HNpat/yXXIEin5ETWXxIwEplC+eDe/vT8vlk1w=
github.com/ncw/swift v1.0.44 h1:EKvOTvUxElbpDWqxsyVaVGvc2IfuOqQnRmjnR2AGhQ4=
github.com/ncw/swift v1.0.44/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
github.com/nsf/termbox-go v0.0.0-20181027232701-60ab7e3d12ed/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd/go.mod h1:4soZNh0zW0LtYGdQ416i0jO0EIqMGcbtaspRS4BDvRQ=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pengsrc/go-shared v0.2.0/go.mod h1:jVblp62SafmidSkvWrXyxAme3gaTfEtWwRPGz5cpvHg=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.8.3/go.mod h1:NxmoDg/QLVWluQDUYG7XBZTLUpKeFa8e3aMf1BfjyHk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46 h1:w2CpS5muK+jyydnmlkqpAhzKmHmMBzBkfYUDjQNS1Dk=
github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46/go.mod h1:U2bmx0hDj8EyDdcxmD5t3XHDnBFnyNNc22n1R4008eM=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sevlyar/go-daemon v0.1.4/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE=
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c h1:fyKiXKO1/I/B6Y2U8T7WdQGWzwehOuGIrljPtt7YTTI=
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/t3rm1n4l/go-mega v0.0.0-20190205172012-55a226cf41da/go.mod h1:XWL4vDyd3JKmJx+hZWUVgCNmmhZ2dTBcaNDcxH465s0=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yunify/qingstor-sdk-go v2.2.15+incompatible/go.mod h1:w6wqLDQ5bBTzxGJ55581UrSwLrsTAsdo9N6yX/8d9RY=
go.mongodb.org/mongo-driver v1.7.2 h1:pFttQyIiJUHEn50YfZgC9ECjITMT44oiN36uArf/OFg=
go.mongodb.org/mongo-driver v1.7.2/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
gogs.inhome.blapointe.com/local/args v0.0.0-20230410154220-44370f257b34 h1:0tuX5dfOksiOQD1vbJjVNVTVxTTIng7UrUdSLF5T+Ao=
gogs.inhome.blapointe.com/local/args v0.0.0-20230410154220-44370f257b34/go.mod h1:YG9n3Clg7683ohkVnJK2hdX8bBS9EojIsd1qPZumX0Y=
gogs.inhome.blapointe.com/local/gziphttp v0.0.0-20230410171240-32da87640b26 h1:zo9E05aBiyvtuuQiT3XjzBnpbm8+bVbzHe7soBQS0Tk=
gogs.inhome.blapointe.com/local/gziphttp v0.0.0-20230410171240-32da87640b26/go.mod h1:Sdj/NB9h3xrzPDqViQAHoDhA5gmpHkrWRXUauvLSA74=
gogs.inhome.blapointe.com/local/logb v0.0.0-20230410154319-880efa39d871 h1:cMGPiwvK/QGg4TfW8VasO6SsS/O7UQmwyKDErV/ozoA=
gogs.inhome.blapointe.com/local/logb v0.0.0-20230410154319-880efa39d871/go.mod h1:E0pLNvMLzY0Kth1W078y+06z1AUyVMWnChMpRFf4w2Q=
gogs.inhome.blapointe.com/local/oauth2 v0.0.0-20230410162733-d39498ff8454 h1:U8gUhe9E97/uG3ne6D1VONCCVC6jjBbF1gDMKn3GCeo=
gogs.inhome.blapointe.com/local/oauth2 v0.0.0-20230410162733-d39498ff8454/go.mod h1:YDG4DAUbmKcQUDWdZAJyoUtX+N2zQIFQ0fz88lAPuiU=
gogs.inhome.blapointe.com/local/router v0.0.0-20230410162418-08ccdc13df87 h1:jlIDVPGFk42puv6NYzRkGFMhsZ0L1AHGRyx5ooGb4Ew=
gogs.inhome.blapointe.com/local/router v0.0.0-20230410162418-08ccdc13df87/go.mod h1:FCXhK6+lzJcxBsptnei6vw9pChuQvr4NtuosngjVJDk=
gogs.inhome.blapointe.com/local/storage v0.0.0-20230410162102-db39d7b02e29 h1:SPSz7yQsEfScqyLlBS5uNSOGeT203BkIkFCL8jrm/FA=
gogs.inhome.blapointe.com/local/storage v0.0.0-20230410162102-db39d7b02e29/go.mod h1:zk8Fe2Ezc2f6oOe2yllsbEhXqssUU1K2faoS0eQ9alY=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/oauth2 v0.0.0-20181120190819-8f65e3013eba h1:YDkOrzGLLYybtuP6ZgebnO4OWYEYVMFSniazXsxrFN8=
golang.org/x/oauth2 v0.0.0-20181120190819-8f65e3013eba/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20181120235003-faade3cbb06a h1:yMfgT1baklxtECXVk3UtZBELVXtVhDbK3/7xLFkFypw=
google.golang.org/api v0.0.0-20181120235003-faade3cbb06a/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -1,8 +1,8 @@
package main
import (
"local/todo-server/config"
"local/todo-server/server"
"gogs.inhome.blapointe.com/local/todo-server/config"
"gogs.inhome.blapointe.com/local/todo-server/server"
"log"
"net/http"
)
@ -12,6 +12,7 @@ func main() {
if err := s.Routes(); err != nil {
panic(err)
}
go s.Async()
log.Println("listening on", config.Port)
if err := http.ListenAndServe(config.Port, s); err != nil {
panic(err)

View File

@ -4,14 +4,16 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>todo breel</title>
<link rel="stylesheet" type="text/css" href="/themes/default/style.css?v=1.4.3" media="all"/>
<link rel="stylesheet" type="text/css" href="/themes/default/print.css?v=1.4.3" media="print"/>
<link rel="stylesheet" type="text/css" href="/themes/default/print.css?v=1.4.3" media="print"/>
<link rel="stylesheet" type="text/css" href="/themes/default/pda.css?v=1.4.3" media="only screen and (max-device-width: 720px)"/>
<meta name="viewport" content="width=device-width, user-scalable=no">
</head>
<body>
<script type="text/javascript" src="/jquery/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="/jquery/jquery-ui-1.8.7.custom.min.js"></script>
<script type="text/javascript" src="/jquery/jquery.autocomplete-1.1.js"></script>
<script type="text/javascript" src="/mytinytodo.js?v=1.4.3"></script>
<script type="text/javascript" src="/mytinytodo_lang.php?v=1.4.3"></script>
<script type="text/javascript" src="/mytinytodo_ajax_storage.js?v=1.4.3"></script>
@ -23,7 +25,7 @@
window.location.href += '/?pda';
}
mytinytodo.mttUrl = "/";
mytinytodo.templateUrl = "/themes/default/";
mytinytodo.db = new mytinytodoStorageAjax(mytinytodo);
@ -71,6 +73,7 @@
<ul class="mtt-tabs"></ul>
<div class="mtt-tabs-add-button" title="New list"><span></span>
</div>
<div style="flex-grow: 100"></div>
<div id="tabs_buttons">
<div class="mtt-tabs-select-button mtt-tabs-button" title="Select list">
<span></span></div>
@ -150,7 +153,7 @@
</div>
</h3>
<form id="taskedit_form" name="edittask" method="post">
<form id="taskedit_form" name="edittask" method="post" onsubmit="return false;">
<input type="hidden" name="isadd" value="0"/>
<input type="hidden" name="id" value=""/>
<div class="form-row form-row-short">
@ -166,6 +169,14 @@
<span class="h">Due </span>
<input name="duedate" id="duedate" value="" class="in100" title="Y-M-D, M/D/Y, D.M.Y, M/D, D.M" autocomplete="off"/>
</div>
<div class="form-row form-row-short">
<span class="h">Loop </span>
<input type="text" name="loop" value="" class="in100" maxlength="30"/>
</div>
<div class="form-row form-row-short">
<span class="h">Cron </span>
<input type="text" name="cron" value="" class="in100" maxlength="30"/>
</div>
<div class="form-row-short-end"></div>
<div class="form-row">
<div class="h">Task</div>
@ -255,6 +266,8 @@
<li class="mtt-menu-delimiter"></li>
<li class="mtt-need-list" id="btnShowCompleted">
<div class="menu-icon"></div>Show completed tasks</li>
<li class="mtt-need-list" id="btnShowLooping">
<div class="menu-icon"></div>Show looping tasks</li>
</ul>
</div>

View File

@ -1,839 +0,0 @@
/*
* jQuery Autocomplete plugin 1.1
*
* Copyright (c) 2009 Jörn Zaefferer
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $
*/
/*
* Changes for myTinyTodo, www.mytinytodo.net
* Copyright (c) 2010 Max Pozdeev
* Dual licensed under the MIT and GPL licenses
*/
;(function($) {
$.fn.extend({
autocomplete: function(urlOrData, options) {
var isUrl = typeof urlOrData == "string";
var isFunc = typeof urlOrData == "function";
options = $.extend({}, $.Autocompleter.defaults, {
url: isUrl ? urlOrData : null,
data: !isUrl && !isFunc ? urlOrData : null,
func: isFunc ? urlOrData : null,
delay: isUrl ? $.Autocompleter.defaults.delay : 10,
max: options && !options.scroll ? 10 : 150
}, options);
// if highlight is set to false, replace it with a do-nothing function
options.highlight = options.highlight || function(value) { return value; };
// if the formatMatch option is not specified, then use formatItem for backwards compatibility
options.formatMatch = options.formatMatch || options.formatItem;
return this.each(function() {
new $.Autocompleter(this, options);
});
},
result: function(handler) {
return this.bind("result", handler);
},
search: function(handler) {
return this.trigger("search", [handler]);
},
flushCache: function() {
return this.trigger("flushCache");
},
setOptions: function(options){
return this.trigger("setOptions", [options]);
},
unautocomplete: function() {
return this.trigger("unautocomplete");
}
});
$.Autocompleter = function(input, options) {
var KEY = {
UP: 38,
DOWN: 40,
DEL: 46,
TAB: 9,
RETURN: 13,
ESC: 27,
COMMA: 188,
PAGEUP: 33,
PAGEDOWN: 34,
BACKSPACE: 8
};
// Create $ object for input element
var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
var timeout;
var previousValue = "";
var cache = $.Autocompleter.Cache(options);
var hasFocus = 0;
var lastKeyPressCode;
var config = {
mouseDownOnSelect: false
};
var select = $.Autocompleter.Select(options, input, selectCurrent, config);
var blockSubmit;
// prevent form submit in opera when selecting with return key
$.browser.opera && $(input.form).bind("submit.autocomplete", function() {
if (blockSubmit) {
blockSubmit = false;
return false;
}
});
// only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
$input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
// a keypress means the input has focus
// avoids issue where input had focus before the autocomplete was applied
hasFocus = 1;
// track last key pressed
lastKeyPressCode = event.keyCode;
switch(event.keyCode) {
case KEY.UP:
event.preventDefault();
if ( select.visible() ) {
select.prev();
} else {
onChange(0, true);
}
break;
case KEY.DOWN:
event.preventDefault();
if ( select.visible() ) {
select.next();
} else {
onChange(0, true);
}
break;
case KEY.PAGEUP:
event.preventDefault();
if ( select.visible() ) {
select.pageUp();
} else {
onChange(0, true);
}
break;
case KEY.PAGEDOWN:
event.preventDefault();
if ( select.visible() ) {
select.pageDown();
} else {
onChange(0, true);
}
break;
// matches also semicolon
case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
case KEY.TAB:
case KEY.RETURN:
if( selectCurrent() ) {
// stop default to prevent a form submit, Opera needs special handling
event.preventDefault();
blockSubmit = true;
return false;
}
break;
case KEY.ESC:
select.hide();
break;
default:
clearTimeout(timeout);
timeout = setTimeout(onChange, options.delay);
break;
}
}).focus(function(){
// track whether the field has focus, we shouldn't process any
// results if the field no longer has focus
hasFocus++;
}).blur(function() {
hasFocus = 0;
if (!config.mouseDownOnSelect) {
hideResults();
}
}).click(function() {
// show select when clicking in a focused field
if ( hasFocus++ > 1 && !select.visible() ) {
onChange(0, true);
}
}).bind("search", function() {
// TODO why not just specifying both arguments?
var fn = (arguments.length > 1) ? arguments[1] : null;
function findValueCallback(q, data) {
var result;
if( data && data.length ) {
for (var i=0; i < data.length; i++) {
if( data[i].result.toLowerCase() == q.toLowerCase() ) {
result = data[i];
break;
}
}
}
if( typeof fn == "function" ) fn(result);
else $input.trigger("result", result && [result.data, result.value]);
}
$.each(trimWords($input.val()), function(i, value) {
request(value, findValueCallback, findValueCallback);
});
}).bind("flushCache", function() {
cache.flush();
}).bind("setOptions", function() {
$.extend(options, arguments[1]);
// if we've updated the data, repopulate
if ( "data" in arguments[1] )
cache.populate();
}).bind("unautocomplete", function() {
select.unbind();
$input.unbind();
$(input.form).unbind(".autocomplete");
});
function selectCurrent() {
var selected = select.selected();
if( !selected )
return false;
var v = selected.result;
previousValue = v;
if ( options.multiple ) {
var words = trimWords($input.val());
if ( words.length > 1 ) {
var seperator = options.multipleSeparator.length;
var cursorAt = $(input).selection().start;
var wordAt, progress = 0;
$.each(words, function(i, word) {
progress += word.length;
if (cursorAt <= progress) {
wordAt = i;
return false;
}
progress += seperator;
});
words[wordAt] = v;
// TODO this should set the cursor to the right position, but it gets overriden somewhere
//$.Autocompleter.Selection(input, progress + seperator, progress + seperator);
v = words.join( options.multipleSeparator );
}
v += options.multipleSeparator;
}
$input.val(v);
hideResultsNow();
$input.trigger("result", [selected.data, selected.value]);
return true;
}
function onChange(crap, skipPrevCheck) {
if( lastKeyPressCode == KEY.DEL ) {
select.hide();
return;
}
var currentValue = $input.val();
if ( !skipPrevCheck && currentValue == previousValue )
return;
previousValue = currentValue;
currentValue = lastWord(currentValue);
if ( currentValue.length >= options.minChars) {
$input.addClass(options.loadingClass);
if (!options.matchCase)
currentValue = currentValue.toLowerCase();
request(currentValue, receiveData, hideResultsNow);
} else {
stopLoading();
select.hide();
}
};
function trimWords(value) {
if (!value)
return [""];
if (!options.multiple)
return [$.trim(value)];
return $.map(value.split(options.multipleSeparator), function(word) {
return $.trim(value).length ? $.trim(word) : null;
});
}
function lastWord(value) {
if ( !options.multiple )
return value;
var words = trimWords(value);
if (words.length == 1)
return words[0];
var cursorAt = $(input).selection().start;
if (cursorAt == value.length) {
words = trimWords(value)
} else {
words = trimWords(value.replace(value.substring(cursorAt), ""));
}
return words[words.length - 1];
}
// fills in the input box w/the first match (assumed to be the best match)
// q: the term entered
// sValue: the first matching result
function autoFill(q, sValue){
// autofill in the complete box w/the first match as long as the user hasn't entered in more data
// if the last user key pressed was backspace, don't autofill
if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
// fill in the value (keep the case the user has typed)
$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
// select the portion of the value not typed by the user (so the next character will erase)
$(input).selection(previousValue.length, previousValue.length + sValue.length);
}
};
function hideResults() {
clearTimeout(timeout);
timeout = setTimeout(hideResultsNow, 200);
};
function hideResultsNow() {
var wasVisible = select.visible();
select.hide();
clearTimeout(timeout);
stopLoading();
if (options.mustMatch) {
// call search and run callback
$input.search(
function (result){
// if no value found, clear the input box
if( !result ) {
if (options.multiple) {
var words = trimWords($input.val()).slice(0, -1);
$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
}
else {
$input.val( "" );
$input.trigger("result", null);
}
}
}
);
}
};
function receiveData(q, data) {
if ( data && data.length && hasFocus ) {
stopLoading();
select.display(data, q);
autoFill(q, data[0].value);
select.show();
} else {
hideResultsNow();
}
};
function request(term, success, failure) {
if (!options.matchCase)
term = term.toLowerCase();
var data = cache.load(term);
// recieve the cached data
if (data && data.length) {
success(term, data);
}
// if function was supplied
else if(options.func)
{
var extraParams = {
timestamp: +new Date()
};
$.each(options.extraParams, function(key, param) {
extraParams[key] = typeof param == "function" ? param() : param;
});
options.func({
data: $.extend({
q: lastWord(term),
limit: options.max
}, extraParams)},
function(data){
var parsed = options.parse && options.parse(data) || parse(data);
cache.add(term, parsed)
success(term, parsed);
}
);
}
// if an AJAX url has been supplied, try loading the data now
else if( (typeof options.url == "string") && (options.url.length > 0) ){
var extraParams = {
timestamp: +new Date()
};
$.each(options.extraParams, function(key, param) {
extraParams[key] = typeof param == "function" ? param() : param;
});
$.ajax({
// try to leverage ajaxQueue plugin to abort previous requests
mode: "abort",
// limit abortion to this input
port: "autocomplete" + input.name,
dataType: options.dataType,
url: options.url,
data: $.extend({
q: lastWord(term),
limit: options.max
}, extraParams),
success: function(data) {
var parsed = options.parse && options.parse(data) || parse(data);
cache.add(term, parsed);
success(term, parsed);
}
});
} else {
// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
select.emptyList();
failure(term);
}
};
function parse(data) {
var parsed = [];
var rows = data.split("\n");
for (var i=0; i < rows.length; i++) {
var row = $.trim(rows[i]);
if (row) {
row = row.split("|");
parsed[parsed.length] = {
data: row,
value: row[0],
result: options.formatResult && options.formatResult(row, row[0]) || row[0]
};
}
}
return parsed;
};
function stopLoading() {
$input.removeClass(options.loadingClass);
};
};
$.Autocompleter.defaults = {
inputClass: "ac_input",
resultsClass: "ac_results",
loadingClass: "ac_loading",
minChars: 1,
delay: 400,
matchCase: false,
matchSubset: true,
matchContains: false,
cacheLength: 10,
max: 100,
mustMatch: false,
extraParams: {},
selectFirst: true,
formatItem: function(row) { return row[0]; },
formatMatch: null,
autoFill: false,
width: 0,
multiple: false,
multipleSeparator: ", ",
highlight: function(value, term) {
return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
},
scroll: true,
scrollHeight: 180
};
$.Autocompleter.Cache = function(options) {
var data = {};
var length = 0;
function matchSubset(s, sub) {
if (!options.matchCase)
s = s.toLowerCase();
var i = s.indexOf(sub);
if (options.matchContains == "word"){
i = s.toLowerCase().search("\\b" + sub.toLowerCase());
}
if (i == -1) return false;
return i == 0 || options.matchContains;
};
function add(q, value) {
if (length > options.cacheLength){
flush();
}
if (!data[q]){
length++;
}
data[q] = value;
}
function populate(){
if( !options.data ) return false;
// track the matches
var stMatchSets = {},
nullData = 0;
// no url was specified, we need to adjust the cache length to make sure it fits the local data store
if( !options.url && !options.func ) options.cacheLength = 1;
// track all options for minChars = 0
stMatchSets[""] = [];
// loop through the array and create a lookup structure
for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
var rawValue = options.data[i];
// if rawValue is a string, make an array otherwise just reference the array
rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
var value = options.formatMatch(rawValue, i+1, options.data.length);
if ( value === false )
continue;
var firstChar = value.charAt(0).toLowerCase();
// if no lookup array for this character exists, look it up now
if( !stMatchSets[firstChar] )
stMatchSets[firstChar] = [];
// if the match is a string
var row = {
value: value,
data: rawValue,
result: options.formatResult && options.formatResult(rawValue) || value
};
// push the current match into the set list
stMatchSets[firstChar].push(row);
// keep track of minChars zero items
if ( nullData++ < options.max ) {
stMatchSets[""].push(row);
}
};
// add the data items to the cache
$.each(stMatchSets, function(i, value) {
// increase the cache size
options.cacheLength++;
// add to the cache
add(i, value);
});
}
// populate any existing data
setTimeout(populate, 25);
function flush(){
data = {};
length = 0;
}
return {
flush: flush,
add: add,
populate: populate,
load: function(q) {
if (!options.cacheLength || !length)
return null;
/*
* if dealing w/local data and matchContains than we must make sure
* to loop through all the data collections looking for matches
*/
if( (!options.url && !options.func) && options.matchContains ){
// track all matches
var csub = [];
// loop through all the data grids for matches
for( var k in data ){
// don't search through the stMatchSets[""] (minChars: 0) cache
// this prevents duplicates
if( k.length > 0 ){
var c = data[k];
$.each(c, function(i, x) {
// if we've got a match, add it to the array
if (matchSubset(x.value, q)) {
csub.push(x);
}
});
}
}
return csub;
} else
// if the exact item exists, use it
if (data[q]){
return data[q];
} else
if (options.matchSubset) {
for (var i = q.length - 1; i >= options.minChars; i--) {
var c = data[q.substr(0, i)];
if (c) {
var csub = [];
$.each(c, function(i, x) {
if (matchSubset(x.value, q)) {
csub[csub.length] = x;
}
});
return csub;
}
}
}
return null;
}
};
};
$.Autocompleter.Select = function (options, input, select, config) {
var CLASSES = {
ACTIVE: "ac_over"
};
var listItems,
active = -1,
data,
term = "",
needsInit = true,
element,
list;
// Create results
function init() {
if (!needsInit)
return;
element = $("<div/>")
.hide()
.addClass(options.resultsClass)
.css("position", "absolute")
.appendTo(document.body);
list = $("<ul/>").appendTo(element).mouseover( function(event) {
if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
$(target(event)).addClass(CLASSES.ACTIVE);
}
}).click(function(event) {
$(target(event)).addClass(CLASSES.ACTIVE);
select();
// TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
input.focus();
return false;
}).mousedown(function() {
config.mouseDownOnSelect = true;
}).mouseup(function() {
config.mouseDownOnSelect = false;
});
if( options.width > 0 )
element.css("width", options.width);
needsInit = false;
}
function target(event) {
var element = event.target;
while(element && element.tagName.toUpperCase() != "LI")
element = element.parentNode;
// more fun with IE, sometimes event.target is empty, just ignore it then
if(!element)
return [];
return element;
}
function moveSelect(step) {
listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
movePosition(step);
var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
if(options.scroll) {
var offset = 0;
listItems.slice(0, active).each(function() {
offset += this.offsetHeight;
});
if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
} else if(offset < list.scrollTop()) {
list.scrollTop(offset);
}
}
};
function movePosition(step) {
active += step;
if (active < 0) {
active = listItems.size() - 1;
} else if (active >= listItems.size()) {
active = 0;
}
}
function limitNumberOfItems(available) {
return options.max && options.max < available
? options.max
: available;
}
function fillList() {
list.empty();
var max = limitNumberOfItems(data.length);
for (var i=0; i < max; i++) {
if (!data[i])
continue;
var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
if ( formatted === false )
continue;
var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
$.data(li, "ac_data", data[i]);
}
listItems = list.find("li");
if ( options.selectFirst ) {
listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
active = 0;
}
// apply bgiframe if available
if ( $.fn.bgiframe )
list.bgiframe();
}
return {
display: function(d, q) {
init();
data = d;
term = q;
fillList();
},
next: function() {
moveSelect(1);
},
prev: function() {
moveSelect(-1);
},
pageUp: function() {
if (active != 0 && active - 8 < 0) {
moveSelect( -active );
} else {
moveSelect(-8);
}
},
pageDown: function() {
if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
moveSelect( listItems.size() - 1 - active );
} else {
moveSelect(8);
}
},
hide: function() {
element && element.hide();
listItems && listItems.removeClass(CLASSES.ACTIVE);
active = -1;
},
visible : function() {
return element && element.is(":visible");
},
current: function() {
return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
},
show: function() {
var offset = $(input).offset();
element.css({
width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
top: offset.top + input.offsetHeight,
left: offset.left
}).show();
if(options.scroll) {
list.scrollTop(0);
list.css({
maxHeight: options.scrollHeight,
overflow: 'auto'
});
if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
var listHeight = 0;
listItems.each(function() {
listHeight += this.offsetHeight;
});
var scrollbarsVisible = listHeight > options.scrollHeight;
list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
if (!scrollbarsVisible) {
// IE doesn't recalculate width when scrollbar disappears
listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
}
}
}
},
selected: function() {
var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
return selected && selected.length && $.data(selected[0], "ac_data");
},
emptyList: function (){
list && list.empty();
},
unbind: function() {
element && element.remove();
}
};
};
$.fn.selection = function(start, end) {
if (start !== undefined) {
return this.each(function() {
if( this.createTextRange ){
var selRange = this.createTextRange();
if (end === undefined || start == end) {
selRange.move("character", start);
selRange.select();
} else {
selRange.collapse(true);
selRange.moveStart("character", start);
selRange.moveEnd("character", end);
selRange.select();
}
} else if( this.setSelectionRange ){
this.setSelectionRange(start, end);
} else if( this.selectionStart ){
this.selectionStart = start;
this.selectionEnd = end;
}
});
}
var field = this[0];
if ( field.createTextRange ) {
var range = document.selection.createRange(),
orig = field.value,
teststring = "<->",
textLength = range.text.length;
range.text = teststring;
var caretAt = field.value.indexOf(teststring);
field.value = orig;
this.selection(caretAt, caretAt + textLength);
return {
start: caretAt,
end: caretAt + textLength
}
} else if( field.selectionStart !== undefined ){
return {
start: field.selectionStart,
end: field.selectionEnd
}
}
};
})(jQuery);

View File

@ -1,7 +1,7 @@
/*
This file is part of myTinyTodo.
(C) Copyright 2009-2010 Max Pozdeev <maxpozdeev@gmail.com>
Licensed under the GNU GPL v2 license. See file COPYRIGHT for details.
This file is part of myTinyTodo.
(C) Copyright 2009-2010 Max Pozdeev <maxpozdeev@gmail.com>
Licensed under the GNU GPL v2 license. See file COPYRIGHT for details.
*/
/**
@ -50,7 +50,7 @@ function getGetParamValue(url, paramName) {
this._lists = {};
this._length = 0;
this._order = [];
this._alltasks = {id: -1, showCompl: 0, sort: 3};
this._alltasks = {id: -1, showCompl: 0, showLooping: 0, sort: 3};
},
length: function () {
return this._length;
@ -204,7 +204,7 @@ function getGetParamValue(url, paramName) {
$('#search').keyup(function (event) {
if (event.keyCode == 27) return;
if ($(this).val() == '') $('#search_close').hide(); //actual value is only on keyup
if ($(this).val() == '') $('#search_close').hide(); //actual value is only on keyup
else $('#search_close').show();
clearTimeout(searchTimer);
searchTimer = setTimeout(function () {
@ -308,12 +308,12 @@ function getGetParamValue(url, paramName) {
$('#lists li.mtt-tab .list-action').live('click', function () {
listMenu(this);
return false; //stop bubble to tab click
return false; //stop bubble to tab click
});
$('#list_all .list-action').click(function (event) {
listMenu(this);
return false; //stop bubble to tab click
return false; //stop bubble to tab click
});
//Priority popup
@ -851,6 +851,7 @@ function getGetParamValue(url, paramName) {
_mtt.db.request('loadTasks', {
list: curList.id,
compl: curList.showCompl,
looping: curList.showLooping,
sort: curList.sort,
search: filter.search,
tag: _mtt.filter.getTags(true),
@ -875,6 +876,43 @@ function getGetParamValue(url, paramName) {
}
function prepareTaskStr(item, noteExp) {
return '' +
'<li id="taskrow_'+item.id+'" class="task-row ' + (item.compl?'task-completed ':'') + item.dueClass + (item.note!=''?' task-has-note':'') +
((curList.showNotes && item.note != '') || noteExp ? ' task-expanded' : '') + prepareTagsClass(item.tags_ids) + '"><div class="task-container">' +
prepareTaskBlocks(item) + "</div></li>\n";
}
function prepareTaskBlocks(item, noteExp) {
var id = item.id;
return ''+
'<div class="task-left">' +
'<div class="task-toggle"></div>' +
'<label><input type="checkbox" '+(flag.readOnly?'disabled="disabled"':'')+(item.compl?'checked="checked"':'')+'/></label>' +
"</div>\n" +
'<div class="task-middle">' +
'<div class="task-middle-top">' +
'<div class="task-through">' +
preparePrio(item.prio,id) +
'<span class="task-title">' + prepareHtml(item.title) + '</span> ' +
(curList.id == -1 ? '<span class="task-listname">'+ tabLists.get(item.listId).name +'</span>' : '') +
prepareTagsStr(item) +
'<span class="task-date">'+item.dateInlineTitle+'</span>' +
'</div>' +
'<div class="task-through-right">' + prepareDueDate(item) + prepareCompletedDate(item) + "</div>" +
'</div>' +
'<div class="task-note-block">' +
'<div id="tasknote'+id+'" class="task-note"><span>'+prepareHtml(item.note)+'</span></div>' +
'<div id="tasknotearea'+id+'" class="task-note-area"><textarea id="notetext'+id+'"></textarea>'+
'<span class="task-note-actions"><a href="#" class="mtt-action-note-save">'+_mtt.lang.get('actionNoteSave') +
'</a> | <a href="#" class="mtt-action-note-cancel">'+_mtt.lang.get('actionNoteCancel')+'</a></span>' +
'</div>' +
'</div>'+
"</div>" +
'<div class="task-actions"><div class="taskactionbtn"></div></div>';
/*
// &mdash; = &#8212; = —
var id = item.id;
var prio = item.prio;
@ -896,6 +934,7 @@ function getGetParamValue(url, paramName) {
'</a> | <a href="#" class="mtt-action-note-cancel">' + _mtt.lang.get('actionNoteCancel') + '</a></span></div>' +
'</div>' +
"</div></li>\n";
*/
}
function prepareHtml(s) {
@ -910,7 +949,7 @@ function getGetParamValue(url, paramName) {
if (prio < 0) {
cl = 'prio-neg prio-neg-' + Math.abs(prio);
v = '&#8722;' + Math.abs(prio);
} // &#8722; = &minus; =
} // &#8722; = &minus; =
else if (prio > 0) {
cl = 'prio-pos prio-pos-' + prio;
v = '+' + prio;
@ -918,7 +957,7 @@ function getGetParamValue(url, paramName) {
else {
cl = 'prio-zero';
v = '&#177;0';
} // &#177; = &plusmn; = ±
} // &#177; = &plusmn; = ±
return '<span class="task-prio ' + cl + '">' + v + '</span>';
}
@ -943,11 +982,24 @@ function getGetParamValue(url, paramName) {
return ' ' + a.join(' ');
}
function prepareDueDate(item) {
return prepareDuedate(item);
}
function prepareDuedate(item) {
if (!item.duedate) return '';
return '<span class="duedate" title="' + item.dueTitle + '"><span class="duedate-arrow">→</span> ' + item.dueStr + '</span>';
}
function prepareCompletedDate(item) {
// &mdash; = &#8212; = —
return '<span class="task-date-completed">' +
'<span title="' + item.dateInlineTitle + '">' + item.dateInline + '</span>&#8212;' +
'<span title="' + item.dateCompletedInlineTitle + '">' + item.dateCompletedInline + '</span>' +
'</span>';
}
function submitNewTask(form) {
if (form.task.value == '') return false;
_mtt.db.request('newTask', {
@ -1233,6 +1285,9 @@ function getGetParamValue(url, paramName) {
case 'btnRssFeed':
feedCurList();
break;
case 'btnShowLooping':
showLoopingToggle();
break;
case 'btnShowCompleted':
showCompletedToggle();
break;
@ -1354,6 +1409,8 @@ function getGetParamValue(url, paramName) {
form.tags.value = item.tags.split(',').join(', ');
form.duedate.value = item.duedate;
form.prio.value = item.prio;
form.loop.value = item.loop;
form.cron.value = item.cron;
$('#taskedit-date .date-created>span').text(item.date);
if (item.compl) $('#taskedit-date .date-completed').show().find('span').text(item.dateCompleted);
else $('#taskedit-date .date-completed').hide();
@ -1370,6 +1427,8 @@ function getGetParamValue(url, paramName) {
form.duedate.value = '';
form.prio.value = '0';
form.id.value = '';
form.loop.value = '';
form.cron.value = '';
toggleEditAllTags(0);
}
@ -1408,11 +1467,17 @@ function getGetParamValue(url, paramName) {
if (flag.readOnly) return false;
if (form.isadd.value != 0)
return submitFullTask(form);
_mtt.db.request('editTask', {
id: form.id.value, title: form.task.value, note: form.note.value,
prio: form.prio.value, tags: form.tags.value, duedate: form.duedate.value
},
var requestBody = {
id: form.id.value,
title: form.task.value,
note: form.note.value,
prio: form.prio.value,
tags: form.tags.value,
duedate: form.duedate.value,
loop: form.loop.value,
cron: form.cron.value,
}
_mtt.db.request('editTask', requestBody,
function (json) {
if (!parseInt(json.total)) return;
var item = json.list[0];
@ -1531,7 +1596,9 @@ function getGetParamValue(url, paramName) {
note: form.note.value,
prio: form.prio.value,
tags: form.tags.value,
duedate: form.duedate.value
duedate: form.duedate.value,
loop: form.loop.value,
cron: form.cron.value,
}, function (json) {
if (!parseInt(json.total)) return;
form.task.value = '';
@ -1621,7 +1688,7 @@ function getGetParamValue(url, paramName) {
submenu = new mttMenu($(this).attr('submenu'));
submenu.$caller = $(this);
submenu.parent = menu;
if (menu.root) submenu.root = menu.root; //!! be careful with circular references
if (menu.root) submenu.root = menu.root; //!! be careful with circular references
else submenu.root = menu;
menu.submenu.push(submenu);
submenu.ts = submenu.container.mttmenu = submenu.root.ts;
@ -1880,6 +1947,8 @@ function getGetParamValue(url, paramName) {
}
if (list.showCompl) $('#btnShowCompleted').addClass('mtt-item-checked');
else $('#btnShowCompleted').removeClass('mtt-item-checked');
if (list.showLooping) $('#btnShowLooping').addClass('mtt-item-checked');
else $('#btnShowLooping').removeClass('mtt-item-checked');
}
function listOrderChanged(event, ui) {
@ -1893,6 +1962,14 @@ function getGetParamValue(url, paramName) {
_mtt.doAction('listOrderChanged', {order: order});
}
function showLoopingToggle() { // todo
var act = curList.showLooping ? 0 : 1;
curList.showLooping = tabLists.get(curList.id).showLooping = act;
if (act) $('#btnShowLooping').addClass('mtt-item-checked');
else $('#btnShowLooping').removeClass('mtt-item-checked');
loadTasks({setLooping: 1});
}
function showCompletedToggle() {
var act = curList.showCompl ? 0 : 1;
curList.showCompl = tabLists.get(curList.id).showCompl = act;
@ -2061,7 +2138,7 @@ function getGetParamValue(url, paramName) {
}
/*
Errors and Info messages
Errors and Info messages
*/
function flashError(str, details) {
@ -2087,7 +2164,7 @@ function getGetParamValue(url, paramName) {
/*
Authorization
Authorization
*/
function updateAccessStatus() {
// flag.needAuth is not changed after pageload
@ -2169,7 +2246,7 @@ function getGetParamValue(url, paramName) {
/*
Settings
Settings
*/
function showSettings() {
@ -2196,4 +2273,4 @@ function getGetParamValue(url, paramName) {
}, 'json');
}
})();
})();

View File

@ -46,7 +46,7 @@
})
*/
$.getJSON(this.mtt.mttUrl + 'ajax.php?loadTasks&list=' + params.list + '&compl=' + params.compl + '&sort=' + params.sort + q, callback);
$.getJSON(this.mtt.mttUrl + 'ajax.php?loadTasks&list=' + params.list + '&compl=' + params.compl + '&looping=' + params.looping + '&sort=' + params.sort + q, callback);
},
@ -64,7 +64,9 @@
note: params.note,
prio: params.prio,
tags: params.tags,
duedate: params.duedate
duedate: params.duedate,
loop: params.loop,
cron: params.cron,
},
callback, 'json');
},
@ -78,7 +80,9 @@
note: params.note,
prio: params.prio,
tags: params.tags,
duedate: params.duedate
duedate: params.duedate,
loop: params.loop,
cron: params.cron,
},
callback, 'json');
},
@ -194,4 +198,4 @@
};
})();
})();

View File

@ -1,13 +1,5 @@
Image files page_white_text.png and calendar.png and some icons in buttons.png
are (or based on) icons from Silk Icons set by Mark James (http://www.famfamfam.com/lab/icons/silk/),
licensed under the Creative Commons Attribution 2.5 License (http://creativecommons.org/licenses/by/2.5/).
Some icons in buttons.png are based on "Silk Companion 1" icons set by Damien Guard
(http://damieng.com/creative/icons/silk-companion-1-icons), licensed under the
Creative Commons Attribution 2.5 License (http://creativecommons.org/licenses/by/2.5/).
Icons in mzl.png are (or based on) icons from Mozilla Source Code,
(http://www.mozilla.org/MPL/#source-code), licensed under the terms
of tri-license (MPL 1.1/GPL 2.0/LGPL 2.1).
rss.svg, rss-disabled.svg - are (or based on) icons by Icons8 from https://icons8.com/icon/13841/rss
calendar.svg - icon by Icons8 from https://icons8.com/icon/__LA9wZgJaqd/calendar
loading48.gif - generated at Preloaders.net
Other images in this directory were made by Max Pozdeev and licensed under the terms of GNU GPL v2+.

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<polyline points="15 4, 15 9, 2 9" stroke-width="1.5" stroke="#000" fill="none" />
<polyline points="6 5, 1 9, 6 13" stroke-width="1.5" stroke="#000" fill="none" />
</svg>

After

Width:  |  Height:  |  Size: 237 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<polygon points="10 3, 4 8, 10 13" fill="#000"/>
</svg>

After

Width:  |  Height:  |  Size: 118 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<polygon points="6 3, 12 8, 6 13" fill="#000"/>
</svg>

After

Width:  |  Height:  |  Size: 117 B

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<!--<rect x="0" y="0" width="16" height="16" fill="red"/>-->
<rect x="1" y="2" width="14" height="12" rx="3" fill="#999999"/>
<polygon points="4 6, 12 6, 8 10" fill="#ffffff"/>
</svg>

After

Width:  |  Height:  |  Size: 248 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<polygon points="4 6, 12 6, 8 10" fill="#888888"/>
</svg>

After

Width:  |  Height:  |  Size: 121 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8">
<polygon points="0 2, 8 2, 4 6" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 115 B

View File

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path fill="#fff" d="M0.5 1.5H15.5V14.5H0.5z"/>
<path fill="#788b9c" d="M15,2v12H1V2H15 M16,1H0v14h16V1L16,1z"/>
<path fill="#f78f8f" d="M0.5 1.5H15.5V4.5H0.5z"/>
<path fill="#c74343" d="M15,2v2H1V2H15 M16,1H0v4h16V1L16,1z"/>
<path fill="#c5d4de" d="M5 7H6V8H5zM7 7H8V8H7zM9 7H10V8H9zM11 7H12V8H11zM3 9H4V10H3zM5 9H6V10H5zM7 9H8V10H7zM9 9H10V10H9zM11 9H12V10H11zM3 11H4V12H3zM5 11H6V12H5zM7 11H8V12H7zM9 11H10V12H9z"/>
</svg>

After

Width:  |  Height:  |  Size: 491 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<polyline points="4 8, 7 12, 13 5" fill="none" stroke-width="2" stroke="#000" />
</svg>

After

Width:  |  Height:  |  Size: 149 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g stroke-width="1.5" fill="none">
<path d="M12.0 12.0l-8-8" stroke="#7f7f7f"/>
<path d="M4.0 12.0l+8-8" stroke="#7f7f7f"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 196 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g stroke-width="1.5" fill="none">
<path d="M12.0 12.0l-8-8" stroke="#000"/>
<path d="M4.0 12.0l+8-8" stroke="#000"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 190 B

View File

@ -1 +1 @@
Direct access disallowed!
Place for Images

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" >
<!-- <rect x="0" y="0" width="16" height="16" fill="lightpink" /> -->
<g stroke="#7f7f7f" fill="none">
<polyline points="10.5 1, 1 1, 1 15, 13 15, 13 7.5" stroke-width="1.0" stroke-linejoin="round"/>
<g stroke-width="1.0" >
<polyline points="7 7, 6 10, 9 9, 15 3, 13 1, 7 7, 6 10" />
<line x1="7" y1="7" x2="9" y2="9" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 406 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14">
<!--<rect x="0" y="0" width="14" height="14" fill="lightpink"/>-->
<polyline points="5 2, 10 7, 5 12" stroke-width="1.5" stroke="#000" fill="none" />
</svg>

After

Width:  |  Height:  |  Size: 217 B

View File

@ -0,0 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs>
<linearGradient id="gradient1" x1="10%" y1="90%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#fff"/>
<stop offset="100%" stop-color="#eee"/>
</linearGradient>
<style type="text/css"><![CDATA[
.line1 { stroke:#333; stroke-width:0.3; }
]]></style>
</defs>
<polygon points="2 1, 11 1, 14 4, 14 15, 2 15" stroke-width="0.2" stroke="#333" fill="#fff" fill-opacity="0.0" />
<line x1="5" y1="4" x2="10" y2="4" class="line1"/>
<line x1="5" y1="6" x2="11" y2="6" class="line1"/>
<line x1="5" y1="8" x2="11" y2="8" class="line1"/>
<line x1="5" y1="10" x2="11" y2="10" class="line1"/>
<line x1="5" y1="12" x2="11" y2="12" class="line1"/>
<polygon points="3 2, 10 2, 10 5, 13 5, 13 14, 3 14" fill="url(#gradient1)" fill-opacity="0.4" />
</svg>

After

Width:  |  Height:  |  Size: 856 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<line x1="3" y1="8" x2="13" y2="8" stroke-width="2" stroke="#333" />
<line x1="8" y1="3" x2="8" y2="13" stroke-width="2" stroke="#333" />
</svg>

After

Width:  |  Height:  |  Size: 207 B

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8">
<title>RSS feed icon</title>
<style type="text/css">
.button {stroke: none; fill: #bbb;}
.symbol {stroke: none; fill: white;}
</style>
<rect class="button" width="8" height="8" rx="1.5" />
<circle class="symbol" cx="2" cy="6" r="1" />
<path class="symbol" d="m 1,4 a 3,3 0 0 1 3,3 h 1 a 4,4 0 0 0 -4,-4 z" />
<path class="symbol" d="m 1,2 a 5,5 0 0 1 5,5 h 1 a 6,6 0 0 0 -6,-6 z" />
</svg>

After

Width:  |  Height:  |  Size: 517 B

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8">
<title>RSS feed icon</title>
<style type="text/css">
.button {stroke: none; fill: orange;}
.symbol {stroke: none; fill: white;}
</style>
<rect class="button" width="8" height="8" rx="1.5" />
<circle class="symbol" cx="2" cy="6" r="1" />
<path class="symbol" d="m 1,4 a 3,3 0 0 1 3,3 h 1 a 4,4 0 0 0 -4,-4 z" />
<path class="symbol" d="m 1,2 a 5,5 0 0 1 5,5 h 1 a 6,6 0 0 0 -6,-6 z" />
</svg>

After

Width:  |  Height:  |  Size: 519 B

View File

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g stroke-width="1.5" fill="none">
<circle cx="8" cy="8" r="7" fill="#000"/>
<path d="M11.0 11.0l-6-6" stroke="#ffffff"/>
<path d="M5.0 11.0l+6-6" stroke="#ffffff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 238 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g stroke-width="1.5" stroke="#7f7f7f" fill="none">
<path d="M14 14l-4-4"/>
<circle cx="7" cy="7" r="4.5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 180 B

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<circle cx="3" cy="8" r="1.5" fill="#333"/>
<circle cx="8" cy="8" r="1.5" fill="#333"/>
<circle cx="13" cy="8" r="1.5" fill="#333"/>
</svg>

After

Width:  |  Height:  |  Size: 200 B

View File

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g fill="none" stroke-width="1.5" stroke="#333" stroke-linecap="round">
<line x1="2" y1="3" x2="14" y2="3"/>
<line x1="2" y1="8" x2="14" y2="8"/>
<line x1="4" y1="13" x2="14" y2="13"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 260 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14">
<!--<rect x="0" y="0" width="14" height="14" fill="lightpink"/>-->
<polyline points="2 6, 7 11, 12 6" stroke-width="2" stroke="#000" fill="none" />
</svg>

After

Width:  |  Height:  |  Size: 216 B

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14">
<!--<rect x="0" y="0" width="14" height="14" fill="lightpink"/>-->
<g fill="#000">
<circle cx="7" cy="2" r="1.5" />
<circle cx="7" cy="7" r="1.5" />
<circle cx="7" cy="12" r="1.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 259 B

View File

@ -188,3 +188,34 @@ h3 {
.mtt-notes-showhide {
display: none;
}
.mtt-tab {
display: none;
}
.mtt-tabs-selected {
display: block;
}
/* BEL */
#taskview ,
#bar ,
br[clear="all"] ,
#task_placeholder > span ,
#mtt_body > h2:first-child {
display: none !important;
}
#toolbar ,
#taskcontainer {
z-index: 15;
}
#taskcontainer {
position: fixed;
top: 6em;
left: 0;
right: 0;
bottom: 0;
overflow-y: scroll;
}

View File

@ -113,4 +113,49 @@ li.task-completed {
#taskview img {
display: none;
}
/* 165 */
@media print {
html { height:0; }
body { height:0; min-height:0; margin:0; }
h2{ display: none; }
h3 { border-bottom:2px solid #777777; }
#toolbar { display: none; }
.topblock { display:none; }
.mtt-tab { display:none; }
.mtt-tab.mtt-tabs-selected { display:block; border:none; background:none; margin:0; }
.mtt-tab.mtt-tabs-selected a { padding:0; display:inline-block; height:auto; }
.mtt-tab.mtt-tabs-selected .list-action { display:none; }
.mtt-tab a span { text-align:left; padding:0; max-width:none; font-size:1.3rem; color:#000; }
.mtt-tabs-add-button { display:none; }
#list_all { display:none; }
#tabs_buttons { display:none; }
#taskview { padding-left:0; font-weight:normal; }
#taskview .arrdown { display:none; }
#tasklist { list-style-type: decimal; list-style-position: outside; }
#tasklist li { border-bottom:none; margin-left:2.5rem; /*border-bottom:1px solid #f0f0f0;*/ }
div.task-note-block { border-left:1px solid #777777; background:none; padding-left:5px; margin-top:5px; padding-top:0px; font-size:9pt; color:#333333; }
.task-middle { margin-left:0px; margin-right:3px; }
.task-left { display:none; }
.task-actions { display:none; }
.task-date { white-space:nowrap; margin-left:10px; }
#tasklist li.today, #tasklist li.past { background-color:#ffffff; border-color:#dedede; }
.task-prio { font-weight:bold; }
li.task-completed { opacity:1; }
#footer_content { border-top:1px solid #777777; background:none; }
#footer_content a { text-decoration:none; color:#000000; }
#mobileordesktop { display: none; }
#tagcloudbtn { display:none; }
.mtt-notes-showhide { display:none; }
#taskview img { display:none; }
}

View File

@ -1,5 +1,5 @@
/*
This file is a part of myTinyTodo.
This file is a part of myTinyTodo.
Copyright 2009-2010 Max Pozdeev <maxpozdeev@gmail.com>
*/
@ -198,7 +198,7 @@ a {
.mtt-tab a {
position: relative;
margin: 0;
font-size: 0.9em;
/*font-size: 0.9em;*/
font-weight: bold;
text-decoration: none;
text-align: center;
@ -454,8 +454,8 @@ a {
}
.mtt-taskbox-icon.mtt-icon-submittask {
background: url(images/mzl.png) 0px -32px no-repeat;
right: 4px;
/*background: url(images/mzl.png) 0px -32px no-repeat;
right: 4px;*/
}
#newtask_adv span {
@ -627,9 +627,9 @@ li.task-expanded .task-toggle {
}
.task-actions {
float: right;
width: 20px;
text-align: right;
/*float: right;*/
/*width: 20px;*/
/*text-align: right;*/
}
.task-date {
@ -760,18 +760,20 @@ li.task-completed .task-title a {
}
a.taskactionbtn {
display: block;
/*display: block;*/
/*
float: right;
height: 15px;
width: 15px;
*/
text-decoration: none;
background: url(images/icons.gif) 0 0 no-repeat;
display: none;
/*background: url(images/icons.gif) 0 0 no-repeat;*/
/*display: none;*/
}
li:hover a.taskactionbtn, a.taskactionbtn.mtt-menu-button-active {
background-position: -16px 0;
display: block;
/*background-position: -16px 0;*/
/*display: block;*/
}
#tasklist.filter-past li, #tasklist.filter-today li, #tasklist.filter-soon li {
@ -794,6 +796,7 @@ li:hover a.taskactionbtn, a.taskactionbtn.mtt-menu-button-active {
min-height: 16px;
display: none;
margin: .7em .5em 0 0;
white-space: pre;
}
li.task-expanded .task-note-block {
@ -1367,3 +1370,402 @@ li.mtt-item-hidden {
min-width: 350px;
}
body { filter: invert(80%); background-color: #222; }
#newtask_adv ,
#tagcloudbtn ,
#settings {
display: none;
}
/* 165 */
/*
This file is a part of myTinyTodo.
Copyright 2009-2010,2020 Max Pozdeev <maxpozdeev@gmail.com>
*/
/* default style */
html { height:100%; overflow-y:scroll; font-size:14px; /* =1rem */ }
body { margin:0px; padding:0px; height:100%; /*background-color:#fff;*/ font-family:"Helvetica Neue",helvetica,arial,sans-serif; }
#wrapper { display:flex; flex-direction:column; align-items:center; height:100%; }
#container { flex: 1 0 auto; width:100%; max-width:1000px; }
#mtt_body { padding:8px; margin-bottom:8px; } /* TODO: can combine container and mtt_body */
#footer { flex-shrink:0; width:100%; max-width:1000px; }
td, th, input, textarea, select { font-family:"Helvetica Neue",helvetica,arial,sans-serif; font-size:1rem; }
form { display: inline; }
h2,h3 { margin:0; }
h2 { font-size:1.5rem; padding-right:10px; }
h3 { border-bottom:2px solid #B5D5FF; margin-bottom:10px; padding:0.6rem 0; font-size:1.1rem; }
a { color:#0000ff; cursor:pointer; text-decoration:underline; }
.topblock { display:flex; align-items:flex-start; margin-bottom:1rem; }
#footer_content { background-color:#b5d5ff; padding:0.6rem; font-size:0.9rem; display:flex; justify-content:space-between; }
#footer_content span:last-child { text-align:center; }
#footer_content a { color:#000000; }
#footer_content a.powered-by-link { font-weight:bold; }
.topblock-title { display:flex; align-items:center; }
.topblock-bar { flex-grow:1; display:flex; justify-content:flex-start; border-bottom:1px solid #b5d5ff; padding-bottom:5px; }
.bar-menu { flex-grow:1; display:flex; justify-content:flex-end; text-align:right; min-height:16px; /* for loading.gif */ }
.nodecor { text-decoration:none; }
#bar_auth::before { content:'\00a0| '; } /* &nbsp; = \00a0 */
#bar_logout { display:none; }
#mtt_body.no-need-auth #bar_auth { display:none; }
#mtt_body.readonly .need-owner { display:none; }
#mtt_body.readonly #bar_auth::before { display:none; }
#authform { overflow: hidden; z-index:100; background-color:#f9f9f9; border:1px solid #cccccc; border-radius:2px; padding:10px; min-width:160px; box-shadow:1px 2px 5px rgba(0,0,0,0.5); }
#authform div { padding:2px 0px; }
#authform div.h { font-weight:bold; }
#authform input { padding:3px; border:1px solid #ccc; border-radius:2px; }
#authform input[type="submit"] { padding:4px; border-radius:3px; background-color:#efefef; }
#loading { background-color:#ffffff; display:none; margin-right:6px; width:16px; height:16px; background:url(images/loading48.gif) no-repeat; background-size:16px 16px; }
#msg { }
#msg .msg-text { font-weight:bold; cursor:pointer; }
#msg .msg-details { padding:1px 4px; background-color:#fff; display:none; max-width:700px; position:absolute; z-index:2; }
#msg.mtt-error .msg-text { background-color:#ff3333; }
#msg.mtt-error .msg-details { border:1px solid #ff3333; }
#msg.mtt-info .msg-text { background-color:#EFC300; }
#msg.mtt-info .msg-details { border:1px solid #EFC300;}
#lists { font-size:0.95rem; display:flex; align-items:flex-start; justify-content:flex-end; }
.tabs-n-button { flex-grow:1; display:flex; align-items:flex-start; }
.tab-height-wrapper { box-sizing:border-box; height:2.2rem; display:flex; align-items:center; }
.mtt-tabs { list-style:none; padding:0; margin:0; display:flex; justify-content:flex-start; flex-wrap:wrap; }
.mtt-tabs li { margin:1px 3px 0 0; }
.mtt-tab { background-color:#fbfbfb; border:1px solid #ededed; border-bottom:none; border-top-right-radius:8px; transition:background-color 0.1s ease-in; }
.mtt-tab a {
margin:0; text-decoration:none; white-space:nowrap; color:#333333; display:inline-block; outline:none;
box-sizing:border-box; height:2.2rem; padding:1px 0.3rem 0 0.3rem; display:flex; align-items:center;
}
.mtt-tab a span { display:inline-block; text-align:center; min-width:75px; max-width:195px; cursor:pointer; padding:0; overflow:hidden; padding-left:0.3rem; padding-right:0.3rem;}
.mtt-tab .list-action { display:none; width:16px; height:16px; background:transparent url(images/arrdown.svg) no-repeat; cursor:pointer; }
.mtt-tab .list-action:hover, .mtt-tab .list-action.mtt-menu-button-active { background-image:url(images/arrdown-hover.svg); }
.mtt-tab.mtt-tabs-selected .list-action { display:block; }
.mtt-tab.mtt-tabs-selected { border-color:transparent; background-color:#ededed; }
.mtt-tab:hover { background-color:#ddd; }
.mtt-tab.mtt-tabs-selected:hover { background-color:#ededed; }
.mtt-tabs.mtt-tabs-only-one li { display:none; }
.mtt-tabs.mtt-tabs-only-one li.mtt-tabs-selected { display:block; }
.mtt-tabs-hidden { display:none; }
.mtt-tabs .mtt-list-sort-placeholder { background-color:#ddd; border:1px solid #aaa; }
.mtt-tabs-alltasks { margin:1px 3px 0 3px; }
.mtt-tabs-alltasks.mtt-tab { border-top-right-radius:0px; border-top-left-radius:8px; }
#tabs_buttons {
padding-left:2px; padding-right:2px;
border-top:1px solid transparent;
margin-top:1px;
}
.mtt-tabs-add-button { display:inline-block; margin-top:1px; border:1px solid #ededed; border-bottom:none; border-top-right-radius: 8px; background-color:#fbfbfb;
padding-left:3px; padding-right:3px;
}
.mtt-tabs-add-button span { display:block; width:16px; height:16px; background:url(images/plus.svg) no-repeat; }
.mtt-tabs-add-button:hover { cursor:pointer; background-color:#ddd; }
#mtt_body.readonly .mtt-tabs-add-button { display:none; }
.mtt-tabs-select-button>span { background:url(images/selectlist2.svg) no-repeat; }
.mtt-img-button { padding:4px; display:block; border-radius:4px; transition:background-color 0.1s ease-in; cursor:pointer; }
.mtt-img-button:hover, .mtt-img-button.mtt-menu-button-active { background-color:#efefef; cursor:pointer; }
.mtt-img-button span { display:block; width:16px; height:16px; }
#mtt_body.no-lists #toolbar > * { visibility:hidden; }
#toolbar { padding:8px; border-bottom:1px solid #DEDEDE; background:#ededed; }
#toolbar .mtt-img-button:hover { background-color:#ddd; }
.arrdown { display:inline-block; height:9px; width:9px; background:url(images/arrdown2.svg) no-repeat; }
.arrdown2 { display:inline-block; height:7px; width:7px; background:url(images/arrdown2.svg) no-repeat; }
.newtask-n-search-container { display:flex; justify-content:flex-end; }
/* Quick Task Add */
.taskbox-c { flex-grow:1; display:flex; align-items:center; }
.mtt-taskbox { position:relative; /*padding-left:22px;*/ /*input padding+border*/ flex-grow:1; max-width:430px; }
#task { color:#444444; background:#fff; height:1.35rem; padding:2px 4px; padding-right:20px; border:1px solid #ccc; border-radius:3px; width:100%; margin-left:-24px; }
#mtt_body.show-all-tasks .taskbox-c, #mtt_body.readonly .taskbox-c { display:none; }
.mtt-taskbox-icon { width:16px; height:16px; position:absolute; top:50%; margin-top:-8px; }
.mtt-taskbox-icon { background:url(images/add.svg) no-repeat; opacity:0.45; right:2px; cursor:pointer; transition:opacity .1s ease-in; }
.mtt-taskbox-icon:hover { opacity:0.7; }
#newtask_adv { margin-left:0.5rem; }
#newtask_adv span { background:url(images/newtask-ext.svg) no-repeat; }
/* Live Search */
#search {
color:#444444; background:#fff; height:1.35rem; padding:2px 20px; width:100%; margin-left:-42px; /*padding+border*/
border:1px solid #ccc; border-radius:10px;
}
#search_close { display:none; }
.mtt-searchbox { position:relative; padding-left:42px; /*input padding+border*/ }
.mtt-searchbox-icon { width:16px; height:16px; position:absolute; top:50%; margin-top:-8px; }
.mtt-searchbox-icon.mtt-icon-search { background:url(images/search.svg) no-repeat; left:4px; }
.mtt-searchbox-icon.mtt-icon-cancelsearch { background:url(images/search-cancel.svg) no-repeat; opacity:0.45; right:4px; cursor:pointer; transition:opacity .1s ease-in; }
.mtt-searchbox-icon.mtt-icon-cancelsearch:hover { opacity:0.7; }
#searchbar { font-size:1rem; font-weight:normal; display:none; margin-top:0.5rem; }
#searchbarkeyword { font-weight:bold; }
/* */
#page_tasks h3 { display:flex; align-items:baseline; }
#mtt_body.no-lists #page_tasks h3 > * { visibility:hidden; }
.mtt-notes-showhide { font-size:1rem; font-weight:normal; margin-left:5px; margin-right:5px; }
.mtt-notes-showhide a { text-decoration:none; border-bottom:1px dotted; }
/* Tag Toolbar */
#mtt-tag-toolbar { font-size:1.0rem; font-weight:normal; margin-top:0.5rem; line-height:1.5rem; display:flex; }
.tag-toolbar-content { flex:auto; margin-bottom:-3px; }
.tag-toolbar-close { flex-shrink:0; }
.tag-toolbar-header { font-weight:normal; }
.tag-filter { margin-left:3px; margin-right:3px; display:inline-flex; align-items:center;
border:1px solid #ddd; border-radius:2rem; background-color:#fff; padding:0.1rem 0.5rem; margin-bottom:3px; cursor:pointer;
}
.tag-filter-exclude { text-decoration:line-through; }
.mtt-filter-header { font-weight:bold; margin-right:.33rem; }
.tag-filter-btn { margin-left:3px; display:inline-block; width:1em; height:1em; /* em! */
background:url(images/closetag.svg) no-repeat; background-size:1em 1em; background-position:bottom center;
opacity:0.45; transition:opacity .1s ease-in; }
.tag-filter:hover .tag-filter-btn { opacity:0.7; }
#mtt-tag-toolbar-close span { background:url(images/close.svg) no-repeat; }
.task-toggle { visibility:hidden; cursor:pointer; width:1rem; height:1rem; display:inline-block; margin-right:2px;
background:url(images/note-toggle.svg) no-repeat; background-size:cover; opacity:0.45;
transition:transform .1s linear, opacity .1s ease-in;
}
.task-toggle::after { content:'0'; color:transparent; } /* for baseline */
.task-toggle:hover { opacity:0.7; }
li.task-has-note .task-toggle { visibility:visible; }
li.task-expanded .task-toggle { transform:rotate(90deg); }
/* #tasklist input[type="checkbox"] { vertical-align:-1px; } /* Chrome */
#tasklist { list-style-type: none; margin: 0; padding: 0;}
#tasklist li { padding:0px 2px; border-bottom:1px solid #DEDEDE; min-height:18px; margin-bottom:1px; background-color:#fff; }
#tasklist .task-container { display:flex; justify-content:flex-start; align-items:baseline; }
#tasklist li:hover, #tasklist li.menu-active { background-color:#f6f6f6; }
.task-left { display:inline-block; }
.task-middle { flex-grow:1; margin:0.6rem 0px; margin-left:5px; min-width:0; /*for long text*/ flex-basis:0; /* IE11 */}
.task-middle-top { display:flex; align-items:baseline; }
.task-actions { flex:0 0 1rem; margin-left:5px; }
.task-left label { min-width:18px; text-align:center; } /* Safari has small checkboxes */
.task-date { color:#999999; font-size:0.8rem; margin-left:4px; display:none; }
.task-date-completed { color:#999999; display:none; margin-left:5px; }
.show-inline-date .task-date { display:inline; }
.show-inline-date li.task-completed .task-date-completed { display:inline; }
.show-inline-date li.task-completed .task-date { display:none; }
.task-through { overflow:hidden; flex-grow:1; }
.task-through-right { }
.task-title a { color:#000000; }
.task-title a:hover { color:#af0000; }
#mtt_body.readonly #tasklist li .task-actions { display:none; }
.task-listname { background-color:#eee; color:#555; padding:0px 3px; }
.task-tags { padding:0px 2px; }
.task-tags .tag { font-size:0.9rem; font-weight:bold; color:#333333; text-decoration:underline; }
.task-tags .tag:hover { }
.duedate { color:#333333; padding:0px; padding-left:1px; margin-left:5px; white-space:nowrap; }
.duedate:before { content:'\2192\20'; }
li.task-completed .duedate { /*font-size:0.8rem;*/ display:none; }
#tasklist li.soon .duedate { color:#008000; }
#tasklist li.today .duedate { color:#FF0000; }
#tasklist li.past .duedate { color:#A52A2A; }
li.task-completed .task-middle { color:#777777;}
li.task-completed .task-through { text-decoration:line-through; }
li.task-completed .task-title a { color:#777777; }
#tasklist li.task-completed { opacity:0.6; }
#tasklist li.task-completed:hover { opacity:1.0; }
#tasklist li.not-in-tagpreview { opacity:0.1; }
#tasklist .mtt-task-placeholder {
min-height:0px; padding:0px; height:18px; line-height:18px;
background-color:#ddd; border:1px solid #aaa;
border-radius:5px;
}
.taskactionbtn { height:1rem; width:1rem; background:url(images/task-menu2.svg) center no-repeat; background-size:1rem; visibility:hidden; /* allocate space */
opacity:0.45; transition:opacity .1s ease-in; }
.taskactionbtn::after { content:'0'; color:transparent; } /* for baseline */
li:hover .taskactionbtn { visibility:visible; }
.taskactionbtn:hover, .taskactionbtn.mtt-menu-button-active { opacity:0.7; cursor:pointer; visibility:visible; }
#tasklist.filter-past li, #tasklist.filter-today li, #tasklist.filter-soon li { display:none; }
#tasklist.filter-past li.past, #tasklist.filter-today li.today, #tasklist.filter-soon li.soon { display:block; }
#tasklist.filter-past li.task-completed, #tasklist.filter-today li.task-completed, #tasklist.filter-soon li.task-completed { display:none; }
.task-note-block { margin-left:2px; color:#777777; background:url(images/note.svg) left 0px no-repeat; background-size:16px 16px;
padding-left:19px; min-height:16px; margin-top:6px; display:none; white-space:normal; word-wrap:break-word; }
li.task-expanded .task-note-block { display:block; }
li.task-completed .task-note-block .task-note { text-decoration:line-through; }
.task-note-area { display:none; margin-bottom:5px; }
.task-note-area textarea { color:#999999; width:100%; display:block; height:65px; }
.task-note-actions { font-size:0.8rem; }
.hidden { display:none; }
.invisible { visibility:hidden; }
.in500 { width:500px; color:#444444; }
.in100 { width:100px; color:#444444; }
.task-note span a { color:#777777; }
.task-note span a:hover { color:#af0000; }
.task-prio { padding-left:2px; padding-right:2px; margin-left:0px; margin-right:5px; cursor:default; }
.prio-neg { background-color:#3377ff; color:#ffffff; }
.prio-pos { background-color:#ff3333; color:#ffffff; }
.prio-pos-1 { background-color:#ff7700; color:#ffffff; }
.prio-zero { /*background-color:#dedede;*/ }
.task-prio.prio-zero { display:none; }
.form-row { margin-top:0.6rem; }
.form-row .h { font-weight:bold; color:#333333; }
.form-row div.h { margin-bottom:3px; }
.form-row-short-end { clear:both; }
#page_taskedit .form-input { padding:3px; border:1px solid #ccc; border-radius:2px; }
#page_taskedit select.form-input { padding:2px; }
#page_taskedit .form-bottom-buttons input { padding:4px; border:1px solid #ccc; border-radius:3px; background-color:#efefef; margin:2px; }
#page_taskedit .form-row .in500 { width:100%; box-sizing:border-box; }
#page_taskedit .form-row textarea.in500 { height:200px; /*resize:none;*/ }
#page_taskedit .form-row-short { float:left; margin-right:12px; }
#page_taskedit .form-bottom-buttons { text-align:center; margin-top:1rem; }
#alltags .tag { font-weight:bold; color:#333333; }
#alltags .tag:hover { background-color:#999988; color:white; }
.alltags-cell { width:1%; white-space:nowrap; padding-left:5px; }
#page_taskedit.mtt-inadd .mtt-inedit { display:none; }
#page_taskedit.mtt-inedit .mtt-inadd { display:none; }
#taskedit-date { font-size:1rem; font-weight:normal; display:inline; color:#777; margin-left:8px; }
a.mtt-back-button { font-size:1rem; }
/* autocomplete */
.ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
.ui-autocomplete { position: absolute; padding:0px; border:1px solid #cccccc; background-color:#f9f9f9; overflow:hidden; z-index:99999; box-shadow:1px 2px 5px rgba(0,0,0,0.5); }
.ui-autocomplete .ui-menu-item { margin: 0px; cursor:default; overflow: hidden; }
.ui-autocomplete .ui-menu-item-wrapper { position: relative; padding:0.3rem 4px; }
.ui-autocomplete .ui-menu-item-wrapper.ui-state-active { background-color:#5a8df0; color:white; }
#priopopup { overflow: hidden; z-index:100; background-color:#f9f9f9; border:1px solid #cccccc; padding:5px; }
#priopopup span { cursor:pointer; border:1px solid #f9f9f9; padding:1px; }
#priopopup .prio-zero:hover { border-color:#dedede; }
#priopopup .prio-neg:hover { border-color:#3377ff; }
#priopopup .prio-pos:hover { border-color:#ff3333; }
#priopopup .prio-pos-1:hover { border-color:#ff7700; }
#tagcloudbtn { font-size:1rem; font-weight:normal; margin-left:auto; }
#mtt_body.show-all-tasks #tagcloudbtn { display:none; }
#tagcloudload { display:none; height:24px; background:url(images/loading48.gif) center no-repeat; background-size:24px 24px; }
#tagcloud {
overflow: hidden; z-index:100; background-color:#fff; border:1px solid #cccccc; padding:5px;
width:100%; max-width:450px; text-align:center;
box-shadow:1px 2px 5px rgba(0,0,0,0.5);
}
#tagcloud.mtt-left-adjusted { margin-left:5px; }
#tagcloud.mtt-right-adjusted { margin-right:5px; }
#tagcloud.mtt-left-adjusted.mtt-right-adjusted { margin-bottom:5px; }
#tagcloud .tag { margin:1px 0px; padding:2px; line-height:140%; color:black; }
#tagcloud .tag:hover { background-color:#999988; color:white; }
#tagcloud .w0 { font-size:80%; }
#tagcloud .w1 { font-size:90%; }
#tagcloud .w2 { font-size:100%; }
#tagcloud .w3 { font-size:110%; }
#tagcloud .w4 { font-size:120%; }
#tagcloud .w5 { font-size:130%; }
#tagcloud .w6 { font-size:140%; }
#tagcloud .w7 { font-size:150%; }
#tagcloud .w8 { font-size:160%; }
#tagcloud .w9 { font-size:170%; }
#tagcloudcancel { float:right; }
#tagcloudcancel span { background:url(images/close.svg) no-repeat; }
.ui-datepicker { width:220px; z-index:202; border: 1px solid #cccccc; background: #ffffff; display:none; padding:2px; box-shadow:1px 2px 5px rgba(0,0,0,0.5); border-radius:5px; }
.ui-datepicker-trigger { cursor:pointer; vertical-align:text-bottom; margin-left:4px; margin-right:4px; width:16px; height:16px; }
.ui-datepicker-calendar { width:100%; border-collapse:collapse; }
.ui-datepicker-calendar thead th { text-align:center; padding:0px; font-size:0.9rem; }
.ui-datepicker-calendar tbody td { text-align:right; padding:1px; }
.ui-datepicker-calendar td a { display:block; text-decoration:none; color:#444444; border:1px solid #cccccc; background-color:#f9f9f9; color:#111; padding:2px; }
.ui-datepicker-calendar td.ui-datepicker-current-day a { background-color:#EAF5FF; color:#222222; border-color:#5980FF; }
.ui-datepicker-calendar td.ui-datepicker-today a { color:#fff; background-color:#ccc; }
.ui-datepicker-calendar td a:hover { border-color:#5a8df0; }
.ui-datepicker-header { padding:3px 0px; }
.ui-datepicker-prev { position:absolute; left:2px; height:20px; text-decoration:none; }
.ui-datepicker-next { position:absolute; right:2px; height:20px; text-decoration:none; }
.ui-datepicker-title { text-align:center; line-height:20px; }
.ui-icon { width:16px; height:16px; text-indent:-99999px; overflow:hidden; }
.ui-datepicker .ui-icon-circle-triangle-w { display:block; position:absolute; top:50%; margin-top:-8px; left:50%; background:url(images/arr-left.svg) no-repeat; }
.ui-datepicker .ui-icon-circle-triangle-e { display:block; position:absolute; top:50%; margin-top:-8px; right:50%; background:url(images/arr-right.svg) no-repeat; }
.mtt-menu-button {
user-select: none;
cursor:pointer;
padding:4px;
transition:background-color 0.1s ease-in;
}
.mtt-menu-button:hover, .mtt-menu-button.mtt-menu-button-active {
background-color:#efefef; border-radius:4px;
}
.mtt-menu-container {
overflow:hidden; z-index:100;
background-color:#f9f9f9; border:1px solid #cccccc; padding:2px 0px;
box-shadow:1px 2px 5px rgba(0,0,0,0.5);
border-radius:5px;
user-select:none;
}
.mtt-menu-container.mtt-left-adjusted { margin-left:5px; }
.mtt-menu-container.mtt-right-adjusted { margin-right:5px; }
.mtt-menu-container.mtt-right-adjusted.mtt-left-adjusted { margin-bottom:5px; }
.mtt-menu-container ul { list-style: none; padding:0; margin:0; }
.mtt-menu-container li { margin:1px 0px; cursor:default; color:#000; white-space:nowrap; padding-top:0.20rem; padding-bottom:0.20rem; padding-left:28px; padding-right:28px; position:relative; }
.mtt-menu-container li:hover, .mtt-menu-container li.mtt-menu-item-active {
background-color:#5a8df0; color:white;
}
.mtt-menu-container li.mtt-item-disabled, .mtt-menu-container li.mtt-item-disabled a { color:#ACA899; }
.mtt-menu-container a { display:block; cursor:default; text-decoration:none; outline:none; color:#000; }
.mtt-menu-container li:hover a { color:white; }
.mtt-menu-container li.mtt-menu-delimiter { height:0px; line-height:0; border-bottom:1px solid #cccccc; margin:2px -1px; padding:0px; font-size:0px; }
.mtt-menu-container .menu-icon { width:16px; height:16px; position:absolute; left:6px; top:50%; margin-top:-8px; }
li.mtt-item-checked .menu-icon { background:url(images/checkmark.svg) no-repeat; }
li.mtt-menu-indicator .submenu-icon {
position:absolute; right:6px; top:50%; margin-top:-8px;
width:16px; height:16px; background:url(images/arr-right.svg) no-repeat;
}
li.mtt-item-hidden { display:none; }
#slmenucontainer li.mtt-list-hidden a { font-style:italic; }
#cmenulistscontainer li.mtt-list-hidden { font-style:italic; }
#mtt_body.readonly .mtt-need-list { display:none; }
#btnRssFeed .menu-icon { background:url(images/rss.svg) no-repeat; }
#btnRssFeed.mtt-item-disabled .menu-icon { background:url(images/rss-disabled.svg) no-repeat; }
#task, #search, #page_taskedit .form-input, #page_taskedit .form-bottom-buttons input { transition: box-shadow .15s ease-in-out; }
#task:focus, #search:focus, #page_taskedit .form-input:focus,
#page_taskedit .form-bottom-buttons input:focus { outline:none; border-color:#5a8df0; box-shadow:0 0 0 2px rgba(90,141,240,0.7); }
.mtt-settings-table { width:100%; border-collapse:collapse; }
.mtt-settings-table th, .mtt-settings-table td { border-bottom:1px solid #dedede; padding:8px; vertical-align:top; }
.mtt-settings-table .form-bottom-buttons { border-bottom:none; text-align:center; }
.mtt-settings-table th { text-align:left; width:210px; padding-left:8px; }
.mtt-settings-table .descr { font-size:0.8rem; font-weight:normal; color:#222; }
.mtt-settings-table .in350 { min-width:350px; }
.mtt-settings-table input { padding:3px; border:1px solid #ccc; border-radius:2px; }
.mtt-settings-table select { padding:2px; border:1px solid #ccc; border-radius:2px; }
.mtt-settings-table .form-bottom-buttons input { padding:4px; border:1px solid #ccc; border-radius:3px; background-color:#efefef; margin:2px; }
.mtt-settings-table input:focus, .mtt-settings-table select:focus { outline:none; border-color:#5a8df0; box-shadow:0 0 0 2px rgba(90,141,240,0.7); }
/* bel post 165 */
.task-actions .taskactionbtn {
width: 2.5em;
}
.task-note {
white-space: pre;
}

View File

@ -134,4 +134,47 @@ h2 {
.alltags-cell {
padding-left: 0;
padding-right: 5px;
}
}
/* 165 */
body { direction:rtl; }
h2 { padding-left:10px; padding-right:0px; }
#loading { margin-left:6px; margin-right:0px; }
.mtt-tabs li { margin-left:3px; margin-right:0px; }
.mtt-tab { border-top-right-radius:0px; border-top-left-radius:8px; }
.mtt-tabs-add-button { border-top-right-radius:0px; border-top-left-radius:8px; }
.mtt-tabs-select-button>span { transform:rotateY(180deg); }
#task { padding-left:20px; padding-right:4px; }
.mtt-taskbox-icon { left:2px; right:auto; transform:rotateY(180deg); }
#newtask_adv { margin-left:0; margin-right:0.5rem; }
.mtt-searchbox-icon.mtt-icon-search { right:4px; left:auto; }
.mtt-searchbox-icon.mtt-icon-cancelsearch { left:4px; right:auto; }
#tagcloudbtn { margin-left:0; margin-right:auto; }
.task-toggle { margin-left:2px; margin-right:0; transform:rotate(180deg); }
.task-middle { margin-left:0; margin-right:5px; }
.task-actions { margin-left:0; margin-right:5px; }
.task-prio, .task-title, .task-date, .task-tags { display:inline-block; } /* TODO: fix this */
.task-prio { margin-left:5px; margin-right:0; }
.task-note-block { margin-left:0; margin-right:2px; padding-left:0; padding-right:19px; background-position:right 0px;}
.task-date { margin-left:0; margin-right:4px; }
.duedate { margin-left:0; margin-right:5px; }
.duedate-arrow { display:none; }
.duedate:before { content:'\20\2190\20'; }
.task-date-completed { margin-left:0; margin-right:5px; }
#tagcloud { box-shadow:-1px 2px 5px rgba(0,0,0,0.5); }
#tagcloudcancel { float:left; }
#taskedit-date { float:left; }
#page_taskedit .form-row-short { float:right; margin-left:12px; margin-right:0; }
.alltags-cell { padding-left:0; padding-right:5px; }
.mtt-menu-container { box-shadow:-1px 2px 5px rgba(0,0,0,0.5); }
.mtt-menu-container .menu-icon { left:auto; right:6px; }
li.mtt-menu-indicator .submenu-icon { left:6px; right:auto; transform:rotate(180deg); }

View File

@ -1,10 +1,13 @@
package ajax
import (
"local/storage"
"local/todo-server/config"
"gogs.inhome.blapointe.com/local/storage"
"gogs.inhome.blapointe.com/local/todo-server/config"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/task"
"log"
"net/http"
"net/url"
"time"
)
type Ajax struct {
@ -82,3 +85,78 @@ func has(params url.Values, k string) bool {
_, ok := params[k]
return ok
}
func (a *Ajax) Async() {
var err error
nextDue := time.Now().Add(config.Loop)
c := time.NewTicker(config.Loop)
c2 := time.NewTicker(config.Loop)
for {
c.Stop()
c.Reset(config.Loop)
c2.Stop()
c2.Reset(time.Until(nextDue))
log.Println("next loop at", time.Until(nextDue), "or", config.Loop)
select {
case <-c.C:
case <-c2.C:
}
nextDue, err = a.loopTasks()
if err != nil {
log.Println("failed to loop tasks", err)
}
}
}
func (a *Ajax) loopTasks() (time.Time, error) {
nextDue := time.Now().Add(time.Hour * 240)
lists, err := a.storageListLists()
if err != nil {
return nextDue, err
}
for _, list := range lists {
tasks, err := a.storageListTasks(list.UUID, func(t *task.Task) bool {
return t.Complete
})
if err != nil {
return nextDue, err
}
for _, task := range tasks {
if !task.Complete {
continue
}
if task.Loop == 0 && task.Cron == "" {
continue
}
var nextTask time.Time
if task.Loop > 0 {
nextTask = task.Completed.Add(task.Loop)
}
if string(task.Cron) != "" {
nextTask2 := task.Cron.Next(task.Completed)
if nextTask2 != (time.Time{}) && (nextTask == (time.Time{}) || nextTask2.Before(nextTask)) {
nextTask = nextTask2
}
}
if time.Now().After(nextTask) {
task.Complete = false
task.Completed = time.Time{}
if nextTask == (time.Time{}) {
task.Title += " !!!INVALID CRON/LOOP!!!"
}
task.Index = list.NextIndex()
if err := a.storageSetTask(list.UUID, task); err != nil {
return nextDue, err
}
if err := a.storageSetList(list); err != nil {
return nextDue, err
}
} else {
if nextTask.Before(nextDue) {
nextDue = nextTask
}
}
}
}
return nextDue, nil
}

View File

@ -1,8 +1,8 @@
package ajax
import (
"local/todo-server/config"
"local/todo-server/server/ajax/list"
"gogs.inhome.blapointe.com/local/todo-server/config"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/list"
"testing"
)

19
server/ajax/form/cron.go Normal file
View File

@ -0,0 +1,19 @@
package form
import (
"log"
"time"
"github.com/robfig/cron/v3"
)
type Cron string
func (c Cron) Next(since time.Time) time.Time {
schedule, err := cron.ParseStandard(string(c))
if err != nil {
log.Printf("failed to parse cron %q: %v", string(c), err)
return time.Time{}
}
return schedule.Next(since)
}

View File

@ -7,6 +7,7 @@ import (
"io"
"io/ioutil"
"net/http"
"regexp"
"strconv"
"strings"
"time"
@ -60,6 +61,38 @@ func ToStrArr(k string) []string {
return outArr
}
func ToDuration(s string) time.Duration {
var d time.Duration
for _, c := range []struct {
key string
d time.Duration
}{
{"d", time.Hour * 24},
{"w", time.Hour * 24 * 7},
} {
daysPattern := regexp.MustCompile(`(^|[a-z])[0-9]+` + c.key + `($|[0-9])`)
idxes := daysPattern.FindAllStringIndex(s, -1)
if len(idxes) > 1 {
return 0
}
for _, idx := range idxes {
substr := s[idx[0]:idx[1]]
for len(substr) > 0 && (substr[0] < '0' || substr[0] > '9') {
substr = substr[1:]
}
for len(substr) > 0 && (substr[len(substr)-1] >= '0' && substr[len(substr)-1] <= '9') {
substr = substr[:len(substr)-1]
}
s = strings.ReplaceAll(s, substr, "")
substr = strings.TrimSuffix(substr, c.key)
n, _ := strconv.Atoi(substr)
d += c.d * time.Duration(n)
}
}
d2, _ := time.ParseDuration(s)
return d2 + d
}
func ToTime(s string) time.Time {
v, err := time.Parse("2006-01-02 15:04:05", s)
if err != nil || v.IsZero() {

View File

@ -5,6 +5,7 @@ import (
"net/http/httptest"
"strings"
"testing"
"time"
)
func TestGet(t *testing.T) {
@ -142,3 +143,29 @@ func testReq() *http.Request {
"d": "e, f,g"
}`))
}
func TestToDuration(t *testing.T) {
cases := map[string]struct {
input string
want time.Duration
}{
"invalid": {},
"simple": {input: "1s", want: time.Second},
"compound": {input: "1m1s", want: time.Minute + time.Second},
"compound:unsorted": {input: "1s1m", want: time.Minute + time.Second},
"compound:extension": {input: "1d1m", want: time.Minute + time.Hour*24},
"extension:day": {input: "1d", want: 24 * time.Hour},
"extension:week": {input: "1w", want: 24 * 7 * time.Hour},
"extension:week,day": {input: "1w1d", want: 24 * 8 * time.Hour},
}
for name, d := range cases {
c := d
t.Run(name, func(t *testing.T) {
got := ToDuration(c.input)
if got != c.want {
t.Fatal(c.input, c.want, got)
}
})
}
}

View File

@ -3,8 +3,8 @@ package ajax
import (
"encoding/json"
"errors"
"local/todo-server/server/ajax/form"
"local/todo-server/server/ajax/list"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/form"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/list"
"net/http"
"sort"
)

View File

@ -2,20 +2,21 @@ package list
import (
"errors"
"local/todo-server/server/ajax/form"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/form"
"net/http"
)
type List struct {
Name string `json:"name"`
UUID string `json:"id"`
Sort int `json:"sort"`
Published int `json:"published"`
ShowCompl int `json:"showCompl"`
ShowNotes int `json:"showNotes"`
Hidden int `json:"hidden"`
Max int `json:"max"`
Index int `json:"index"`
Name string `json:"name"`
UUID string `json:"id"`
Sort int `json:"sort"`
Published int `json:"published"`
ShowCompl int `json:"showCompl"`
ShowLooping int `json:"showLooping"`
ShowNotes int `json:"showNotes"`
Hidden int `json:"hidden"`
Max int `json:"max"`
Index int `json:"index"`
}
func New(r *http.Request) (*List, error) {
@ -41,6 +42,10 @@ func (l *List) SetShowCompl(state bool) {
set(state, &l.ShowCompl)
}
func (l *List) SetShowLooping(state bool) {
set(state, &l.ShowLooping)
}
func (l *List) SetShowNotes(state bool) {
set(state, &l.ShowNotes)
}

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"errors"
"fmt"
"local/todo-server/server/ajax/form"
"local/todo-server/server/ajax/list"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/form"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/list"
"net/http"
"net/http/httptest"
"strings"

View File

@ -3,10 +3,10 @@ package ajax
import (
"bytes"
"encoding/gob"
"local/storage"
"local/todo-server/server/ajax/form"
"local/todo-server/server/ajax/list"
"local/todo-server/server/ajax/task"
"gogs.inhome.blapointe.com/local/storage"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/form"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/list"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/task"
"net/http"
"path"
"sort"
@ -62,11 +62,11 @@ func (a *Ajax) storageListTasks(listID string, filters ...func(t *task.Task) boo
if err != nil {
return nil, err
}
includeComplete := true
includeComplete := false
for _, f := range filters {
t := &task.Task{Complete: true}
if !f(t) {
includeComplete = false
if f(t) {
includeComplete = true
}
}
if includeComplete {
@ -77,11 +77,16 @@ func (a *Ajax) storageListTasks(listID string, filters ...func(t *task.Task) boo
results = append(results, completeResults...)
}
tasks := []*task.Task{}
uuids := map[string]struct{}{}
for _, result := range results {
taskID := path.Base(result)
if taskID == "" {
continue
}
if _, ok := uuids[taskID]; ok {
continue
}
uuids[taskID] = struct{}{}
task, err := a.storageGetTask(taskID)
if err != nil {
return nil, err

View File

@ -1,8 +1,8 @@
package ajax
import (
"local/todo-server/server/ajax/list"
"local/todo-server/server/ajax/task"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/list"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/task"
"net/http/httptest"
"testing"
)

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"errors"
"fmt"
"local/todo-server/server/ajax/form"
"local/todo-server/server/ajax/task"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/form"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/task"
"net/http"
"sort"
"strconv"
@ -20,15 +20,24 @@ type taskWithDelta struct {
func (a *Ajax) loadTasks(w http.ResponseWriter, r *http.Request) error {
listID, _, _ := a.Cur(r)
filterComplete := filterComplete(form.Get(r, "compl"))
filterLooping := filterLooping(form.Get(r, "looping"))
filterTags := filterTags(form.ToStrArr(form.Get(r, "t")))
filterSubstr := filterSubstr(form.Get(r, "s"))
tasks, err := a.storageListTasks(listID, filterComplete, filterTags, filterSubstr)
tasks, err := a.storageListTasks(listID, filterComplete, filterTags, filterSubstr, filterLooping)
if err != nil {
return err
}
return json.NewEncoder(w).Encode(map[string]interface{}{"list": tasks})
}
func filterLooping(looping string) func(t *task.Task) bool {
return func(t *task.Task) bool {
hasLoop := t.Loop > 0 || t.Cron != ""
onlyLooping := looping == "1"
return !onlyLooping || hasLoop
}
}
func filterComplete(compl string) func(t *task.Task) bool {
return func(t *task.Task) bool {
return compl == "" || !t.Complete || (compl == "1" && t.Complete)

View File

@ -4,7 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"local/todo-server/server/ajax/form"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/form"
"net/http"
"regexp"
"strings"
@ -23,6 +23,8 @@ type Task struct {
Complete bool
Note []string
Due time.Time
Loop time.Duration
Cron form.Cron
Index int
}
@ -42,8 +44,9 @@ func New(r *http.Request) (*Task, error) {
Tags: append(StrList(form.ToStrArr(form.Get(r, "tag"))), StrList(form.ToStrArr(form.Get(r, "tags")))...),
Created: time.Now(),
Edited: time.Now(),
Due: form.ToTime(form.Get(r, "duedate")),
Due: form.ToTime(form.Get(r, "duedate")),
Loop: form.ToDuration(form.Get(r, "loop")),
Cron: form.Cron(form.Get(r, "cron")),
}
task.SetNote(form.Get(r, "note"))
return task, task.validate()
@ -73,7 +76,9 @@ func (t *Task) MarshalJSON() ([]byte, error) {
// "dueClass":"",
// "dueStr":"",
// "dueInt":33330000,
// "dueTitle":"Due "}
// "dueTitle":"Due ",
// "loop": "1m",
// "cron": "* * * * *"}
// ]}
fullFormat := "02 Jan 2006 03:04 PM"
shortFormat := "02 Jan"
@ -109,6 +114,8 @@ func (t *Task) MarshalJSON() ([]byte, error) {
"dueStr": t.Due.Format(shortFormat),
"dueInt": t.Due.Unix(),
"dueTitle": "Due ",
"loop": t.Loop.String(),
"cron": t.Cron,
}
if t.Due.IsZero() {
for k := range m {

View File

@ -2,8 +2,8 @@ package ajax
import (
"encoding/json"
"local/todo-server/server/ajax/form"
"local/todo-server/server/ajax/task"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/form"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax/task"
"net/http"
"net/http/httptest"
"path"

View File

@ -3,9 +3,6 @@ package server
import (
"fmt"
"io"
"local/gziphttp"
"local/router"
"local/todo-server/config"
"log"
"net/http"
"net/url"
@ -13,6 +10,11 @@ import (
"path"
"path/filepath"
"strings"
"gogs.inhome.blapointe.com/local/gziphttp"
"gogs.inhome.blapointe.com/local/oauth2/oauth2client"
"gogs.inhome.blapointe.com/local/router"
"gogs.inhome.blapointe.com/local/todo-server/config"
)
func (s *Server) Routes() error {
@ -22,28 +24,31 @@ func (s *Server) Routes() error {
}{
{
path: "/",
handler: s.gzip(s.index),
handler: s.index,
},
{
path: "/mytinytodo_lang.php",
handler: s.gzip(s.lang),
handler: s.lang,
},
{
path: fmt.Sprintf("/themes/%s%s", router.Wildcard, router.Wildcard),
handler: s.gzip(s.handleDeviceCSS),
handler: s.handleDeviceCSS,
},
{
path: fmt.Sprintf("%s%s", router.Wildcard, router.Wildcard),
handler: s.gzip(s.phpProxy),
handler: s.phpProxy,
},
{
path: "/ajax.php",
handler: s.gzip(s.HandleAjax),
handler: s.HandleAjax,
},
}
for _, route := range routes {
if err := s.Add(route.path, route.handler); err != nil {
handler := route.handler
handler = s.gzip(handler)
handler = s.oauth(handler)
if err := s.Add(route.path, handler); err != nil {
return err
}
}
@ -79,6 +84,10 @@ func (s *Server) lang(w http.ResponseWriter, r *http.Request) {
`)
}
func (s *Server) toindex(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/", http.StatusSeeOther)
}
func (s *Server) index(w http.ResponseWriter, r *http.Request) {
f, err := os.Open(path.Join(config.Root, "index.html"))
if err != nil {
@ -96,19 +105,61 @@ func (s *Server) phpProxy(w http.ResponseWriter, r *http.Request) {
s.static(w, r)
return
}
url, err := url.Parse(config.MyTinyTodo)
url, err := url.Parse("http://127.0.0.1:64123")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
} else {
log.Println("WOULD proxy", url.String(), r.URL.Path)
s.index(w, r)
s.toindex(w, r)
//proxy := httputil.NewSingleHostReverseProxy(url)
//proxy.ServeHTTP(w, r)
}
}
func (s *Server) static(w http.ResponseWriter, r *http.Request) {
s.fileServer.ServeHTTP(w, r)
if err := s._static(w, r); err != nil {
s.toindex(w, r)
}
}
func (s *Server) _static(w http.ResponseWriter, r *http.Request) error {
if r.Method != http.MethodGet {
http.FileServer(s.fileDir).ServeHTTP(w, r)
return nil
}
f, err := s.fileDir.Open(path.Clean(r.URL.Path))
if err != nil {
return err
}
defer f.Close()
info, err := f.Stat()
if err != nil {
return err
}
if info.IsDir() {
r.URL.Path = path.Join(r.URL.Path, "index.html")
f, err = s.fileDir.Open(r.URL.Path)
defer f.Close()
if err != nil {
return err
}
}
gziphttp.SetContentTypeIfMedia(w, r)
_, err = io.Copy(w, f)
return err
}
func (s *Server) oauth(h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if config.OAuth != "" {
err := oauth2client.Authenticate(config.OAuth, r.Host, w, r)
if err != nil {
log.Println("oauth failure", r.Host, ":", err)
return
}
}
h(w, r)
}
}
func (s *Server) gzip(h http.HandlerFunc) http.HandlerFunc {

View File

@ -1,16 +1,16 @@
package server
import (
"local/router"
"local/todo-server/config"
"local/todo-server/server/ajax"
"gogs.inhome.blapointe.com/local/router"
"gogs.inhome.blapointe.com/local/todo-server/config"
"gogs.inhome.blapointe.com/local/todo-server/server/ajax"
"net/http"
)
type Server struct {
*ajax.Ajax
*router.Router
fileServer http.Handler
fileDir http.Dir
}
func New() *Server {
@ -18,10 +18,10 @@ func New() *Server {
if err != nil {
panic(err)
}
fileServer := http.FileServer(http.Dir(config.Root))
fileDir := http.Dir(config.Root)
return &Server{
Ajax: ajax,
Router: router.New(),
fileServer: fileServer,
Ajax: ajax,
Router: router.New(),
fileDir: fileDir,
}
}

@ -1 +0,0 @@
Subproject commit e21afea391ecac5c5f5b47639e5ce8cb8b7eb693