-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement cache and TaskGroup #23
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,21 @@ | ||
require 'active_support' | ||
require 'active_support/core_ext/hash' | ||
|
||
module Dovico | ||
APP_DIRECTORY = "#{Dir.home}/.dovico/" | ||
end | ||
|
||
require 'dovico/version' | ||
require 'dovico/api_client' | ||
require 'dovico/app' | ||
require 'dovico/config_parser' | ||
require 'dovico/model/assignment' | ||
require 'dovico/model/time_entry_formatter' | ||
require 'dovico/model/time_entry_generator' | ||
require 'dovico/model/assignments' | ||
require 'dovico/model/client' | ||
require 'dovico/model/employee' | ||
require 'dovico/model/project' | ||
require 'dovico/model/task' | ||
require 'dovico/model/task_group' | ||
require 'dovico/model/time_entry' | ||
require 'dovico/model/time_entry_formatter' | ||
require 'dovico/model/time_entry_generator' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
require 'fileutils' | ||
|
||
module Dovico | ||
class Assignments | ||
class CacheError < RuntimeError; end | ||
|
||
attr_reader :assignments, :myself | ||
|
||
CACHE_FILE = "#{APP_DIRECTORY}/assignments.json" | ||
CACHE_VERSION = "2" | ||
|
||
def initialize(force_refresh: false) | ||
if !force_refresh | ||
load_from_cache! | ||
end | ||
|
||
@assignments ||= Assignment.fetch_all | ||
@myself ||= Employee.myself | ||
|
||
save_to_cache! | ||
end | ||
|
||
def format_tree | ||
assignments.map(&:to_s).join("\n") | ||
end | ||
|
||
def find_project_task(project_id, task_id) | ||
project = assignments.find {|assignment| assignment.find_object(Project, project_id) } | ||
task = project.find_object(Task, task_id) | ||
|
||
if project.nil? || task.nil? | ||
raise "Can't find project##{project_id}/task##{task_id}. Try with --force-refresh option" | ||
end | ||
|
||
[project, task] | ||
end | ||
|
||
private | ||
|
||
def load_from_cache! | ||
raise CacheError.new("Cache does not exist") unless File.exists?(CACHE_FILE) | ||
|
||
json = JSON.parse(File.read(CACHE_FILE)) | ||
raise CacheError.new("Cache version mismatch") unless json["version"] == CACHE_VERSION | ||
|
||
@assignments = Assignment.unserialize(json["assignments"]) unless json["assignments"].nil? | ||
@myself = Employee.unserialize(json["myself"]) unless json["myself"].nil? | ||
rescue JSON::ParserError, CacheError => e | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤔 wdyt of logging something to stderr on CacheError exceptions? |
||
end | ||
|
||
def save_to_cache! | ||
cache = { | ||
version: CACHE_VERSION, | ||
assignments: @assignments, | ||
myself: @myself, | ||
} | ||
|
||
FileUtils.mkdir_p(APP_DIRECTORY) | ||
File.write(CACHE_FILE, cache.to_json) | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module Dovico | ||
class Client < Assignment | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,4 @@ | ||
require 'active_attr' | ||
|
||
module Dovico | ||
class Project < Assignment | ||
|
||
attribute :tasks | ||
|
||
def self.parse(hash) | ||
project = super(hash) | ||
project.tasks ||= [] | ||
project | ||
end | ||
|
||
def self.all | ||
projects_search = ApiClient.get_paginated_list(URL_PATH, "Assignments") | ||
projects = projects_search["Assignments"].map {|project_hash| parse(project_hash) } | ||
|
||
projects.each do |project| | ||
tasks_search = ApiClient.get_paginated_list("#{URL_PATH}/#{project.assignement_id}", "Assignments") | ||
tasks = tasks_search["Assignments"].map {|task_hash| Task.parse(task_hash) } | ||
|
||
project.tasks = tasks.sort_by do |task| | ||
task.id | ||
end | ||
end | ||
|
||
projects | ||
end | ||
|
||
def self.format_all | ||
text = " Project | Task | Description\n" | ||
text += all.map(&:to_s).join("\n") | ||
end | ||
|
||
def to_s | ||
text = '' | ||
|
||
if tasks.count > 0 | ||
text += tasks.map do |task| | ||
sprintf " %7d | %4d | %s: %s", id, task.id, name, task.name | ||
end.join("\n") | ||
else | ||
text += sprintf " %7d | | %s (No tasks linked)", id, name | ||
end | ||
|
||
text | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
require 'active_attr' | ||
|
||
module Dovico | ||
class Task < Assignment | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module Dovico | ||
class TaskGroup < Assignment | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. May it make sense to group various assignment types in
is a bit confusing, I'm thinking rather of an API client then of an assignment |
||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File.join(APP_DIRECTORY, 'assgnments.json')
will be more portable I think