Age | Commit message (Collapse) | Author |
|
Now that `Profile` and `Project` have been subsumed into `TimeEntry`
(f017c462593496efbc0810ec2603da49a2e3d9d8), these arguments should no
longer be here and their data should come from `TimeEntry` instead.
|
|
Time spent on a project can be variable from day to day. The time
shouldn't be stored on the project, and should no longer be passed in
config.toml. Instead it should be a part of `TimeEntry`, which it now
is.
|
|
A new function that creates a `TimeEntry` build from a `Profile`,
`Project`, and a few other parameters. Makes it a bit easier to create
`TimeEntry`ies.
Additionally, add a `PersonID` field to `TimeEntry` so we can pass it
around as a self-contained thing without worrying about having to pass
a `Profile` along with it.
|
|
A slightly altered function that only submits a single time entry and
uses our new `Profile`, `Project`, and `TimeEntry` types.
|
|
Require the config.toml file to come with a `[profile]` hash. This
allows us to get the "person_id" for correct submission to TimeTask.
Additionally, add a TOML tag to `PersonID` in `Profile` to allow it to
be decoded.
|
|
Otherwise the TOML decoder didn't know how to parse it.
|
|
Change the function to use our new `TimeEntry` type, which doesn't
demand asking for IDs as it already has them built in.
Additionally, remove the loop here as we only want to submit a single
time entry at a time.
Add a new `Profile` type that holds onto the user's person_id. Forgot
that existed. We'll have users fill that into their config.toml file.
|
|
Uncomment these functions. Looks like they'll still be useful after all.
Just need a little munging to fit them into the usage of submitting a
single time entry and using our new `Project` and `TimeEntry` types.
|
|
Change [Client, Project, Module, Task, WorkType] fields to `int`s
instead of strings.
In the new era, with config2.toml, these fields will be populated
directly with the proper int IDs from TimeTask. Thus these fields need
to be `int`s.
Get rid of the `UnmarshalYAML` function as in the new era we won't be
submitting time entries by YAML file. Instead they will be submitted
directly via command line arguments (plus the IDs coming from the config
file).
|
|
|
|
This corresponds to a "project" entry in the new config2.toml file. (See
13c84cd9973458750305c72a919cf921d9b22b04).
Instead of decoding generic `interface{}`s as projects from the TOML,
make them a real type.
The reason why we're using `int`s where we used to use strings is that
the new TOML format will have users write IDs directly in the config
file, instead of having the program automatically search for those IDs
and use them as we had previously designed. Maybe we'll bring that
functionality back at some point, but for now it's too bothersome to
implement and I don't consider it worth the trouble.
|
|
Half get rid of a lot of code. I don't like and don't want to use our
old field types. Get rid of them and the code in 'http.go' that depends
on them.
Also get rid of the time entry submission code in 'main.go' as that's
going to be redone.
|
|
* Get rid of the 'yaml' import since we're now using 'toml' instead.
* Get rid of commented code that's no longer relevant.
* Get rid of test code that checked that the config loaded
correctly.
|
|
Construct a new config format, written in TOML. Read that format in
when starting the program. This new format has the benefit of using
project name aliases as keys. The goal will be to allow users to send
one of those aliases as a command line argument to the program,
and thus to have the program post a TimeTask entry for that project.
Here's an idea of what the new format looks like:
[auth]
username = "example"
password_cmd = ""
[projects.myprojectalias]
client = ...
project = ...
module = ...
task = ...
work_type = ...
time = 7
billable = true
[projects.project2]
client = ...
project = ...
module = ...
task = ...
work_type = ...
time = 7
billable = true
Eventually, we'll need to remove the `interface{}` from the
`Projects` map value and replace it with a real type, but this was just
to test that it was possible to get us a nice map from the TOML.
|
|
Add info about the project, the fact that it's been abandoned and why,
and license information.
|
|
|
|
Use a GitHub path instead of my custom project path to allow us to
publish the project.
|
|
Get Monday's date from the current week using the When library (which
provides natural language date parsing, making it super easy to get a
time object for Monday). Then when creating the `TimeEntry`ies for the
generator, fill in Monday–Friday's dates in the output.
|
|
A function to generate a weekly time sheet.
Add a new `defaults` key to the config.yml file. Looks like this:
defaults:
client:
project:
module:
task:
work_type:
time:
billable:
This will be used to fill in default values when a timesheet is
generated.
|
|
The date is allowed to be empty in the config defaults hash. Don't error
if it is.
|
|
These tell the Time Task form endpoint that we're submitting a
multiple-time submission request.
|
|
|
|
Because `strings.Itoa` is so much easier to call than
`strconv.ParseUint`, and I needed to parse ints into strings to build
the URL params in `buildSubmissionParams`
(17f4ecc63615e3f3bef21a80f15e7c7b0e0cffa1).
|
|
Function that takes a list of `TimeEntry`ies and builds the necessary
URL params for submission to the Time Task form endpoint.
|
|
Not relevant. See 89f766854443a6f7ae20c330547083fd0e075ba9.
|
|
We want to be able to get Client, Project, etc. objects given their
name. These functions will look through the fields or objects containing
a list of the thing looked for and return if if its name matches the
search string.
Originally had the idea to generalise the body of the function, but had
trouble making the types generic. Still on the table for later if we
want to deduplicate the code. For now I'm leaving in the repetition
because it works and I don't care with this project.
|
|
Embedding this struct prevented us from correctly unmarshalling data
into them. This is because they need to be created like:
Client{IDName{ID: , Name: ,}}
The fields can't be added in directly.
Save ourselves the headache and just manually repeat the fields. So that
importing works right.
|
|
Forgot to add this field originally. Do the same as when we added the
`Time` field.
|
|
Fix 7a8db5312bbb43c986fbae7aa14960e22080b03b to ensure that the `Time`
field actually gets unmarshalled into `TimeEntry` structs.
|
|
We'll be needing to refer to these fields as named types, so create
types for them and reference them in the config object.
|
|
Include billable hours field.
|
|
Expect a timesheet file as the last argument to the program. Parse the
contents into `TimeEntry` objects. `TimeEntry`ies will then be able to
be POSTed to Time Task to submit times.
The time entries input file is a YAML document in this format:
- client: A client
project: A project
module: A module
task: A task
work_type: type
date: 2017-03-06
time: 7
billable: true
description:
It contains an array where each element is a time entry.
Had a lot of trouble parsing the date into a `time.Time`. Finally
realised that my first and biggest problem was somehow I was importing
`yaml.v1` instead of `yaml.v2`, and thus my `UnmarshalYAML` function was
never getting called.
Wanted a way to get the time as a string and parse it myself into a
time. At first tried using an `UnmarshalText` function:
type Time time.Time
func (t *Time) UnmarshalText(text []byte) error {
parsed, err := time.Parse("2006-01-02", string(text))
if err == nil {
*t = Time(parsed)
}
return err
}
But in order to do that I had to make a type alias to `time.Time`. Doing
so was not ideal, because then I'd have to convert my `Time` into a
`time.Time` any time I wanted to use it for real.
Ended up going with a suggestion from here:
https://mlafeldt.github.io/blog/decoding-yaml-in-go/
Creating an auxiliary struct in `UnmarshalYAML` to unmarshal the date
into a string and then parse it myself as a date. I don't really like it
because it's a lot of ceremony just to parse one type myself, but can't
come up with a better solution right now so there you have it.
|
|
* Extract the config loading lines from `main` so we can give them a name
* Make `config` available globally
|
|
Set up a configuration object which gets read from a YAML config file.
Currently using an uncommitted test file that looks like this (with some
data filled in:
auth:
username:
password_cmd:
fields:
person_id:
clients:
- id:
name:
projects:
- id:
name:
modules:
- id:
name:
tasks:
- id:
name:
work_types:
- id:
name:
The program just outputs the config object so I can see whether it's
working. The data will then be used to associate ids for time
submission.
|
|
|
|
Verify errors and check the response body to ensure successful login.
|
|
Ignore /_private for reference files.
|
|
Fill in the `Login` function to actually log in to Time Task. Pass
credentials in via test command flags.
Referenced https://gist.github.com/varver/f327ef9087ebf76aa4c4 for the
cookie setup.
|
|
Make a sample GET request using `net/http`.
|