Last active
May 10, 2019 18:49
-
-
Save 2shortplanks/4ca8458953f51f665ddb3bdb6059141f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
use warnings; | |
use HTTP::Tiny; | |
use IPC::Run3 qw( run3 ); | |
use JSON::PP qw( encode_json decode_json ); | |
my $PROJECT_ID = ...; # The numbers at the end of your project URL | |
my $TOKEN = ...; # "API token" from https://www.pivotaltracker.com/profile | |
my $PTUSERNAME = ...; # "User name" from https://www.pivotaltracker.com/profile | |
my $FOLDERID = ...; # the id of the folder to create projects in (the end of what you get when right click on folder and "Copy as link") | |
my $of_projects = get_of_data(); | |
my $pt_projects = get_pt_data(); | |
for my $project (@{ $pt_projects->{stories}{stories} } ) { | |
next if of_data_contains_url( $project->{url} ); | |
create_new_project( | |
name => "PT: $project->{name}", | |
note => <<"NOTE", | |
$project->{url} | |
$project->{description} | |
NOTE | |
); | |
} | |
### | |
# talking to PT | |
### | |
sub get_pt_data { | |
my $response = HTTP::Tiny->new->get( | |
"https://www.pivotaltracker.com/services/v5/projects/$PROJECT_ID/search?query=mywork:$PTUSERNAME", | |
{ | |
headers => { | |
'X-TrackerToken' => $TOKEN, | |
}, | |
}, | |
); | |
unless ($response->{success}) { die "$response->{status} $response->{reason}" } | |
return decode_json($response->{content}); | |
} | |
### | |
# talking to OF | |
### | |
sub get_of_data { return run_jxa(<<'JAVASCRIPT') } | |
JSON.stringify( | |
Application('OmniFocus') | |
.defaultDocument | |
.tags["pt"] | |
.remainingTasks() | |
.map(e => e.containingProject()) | |
.filter(e => e) | |
.sort(a => a.id()) | |
.filter( (v,i,a) => (i === 0) || (v.id() !== a[i-1].id() )) | |
.map(a => ({ name : a.name(), note : a.note.text() })) | |
); | |
JAVASCRIPT | |
sub create_new_project { return run_jxa(<<'JAVASCRIPT', { @_, folder_id => $FOLDERID }) } | |
var omnifocus = Application("OmniFocus"); | |
var project = omnifocus.Project({ | |
name: data.name, | |
note: data.note, | |
}); | |
omnifocus.defaultDocument.folders.byId(data.folder_id).projects.push(project); | |
var tag = omnifocus.defaultDocument.tags["pt"]; | |
omnifocus.add( | |
tag, | |
{ to: project.rootTask().tags } | |
); | |
{ done: true }; | |
JAVASCRIPT | |
sub run_jxa { | |
my $javascript = shift; | |
my $input = shift; | |
$javascript = "let data = @{[ encode_json($input // {}) ]};\n$javascript"; | |
my $stdout = q{}; | |
my $stderr = q{}; | |
run3([ '/usr/bin/osascript', '-l', 'JavaScript' ], \$javascript, \$stdout, \$stderr); | |
die $? if $?; | |
die $stderr if $stderr; | |
return decode_json($stdout); | |
} | |
sub of_data_contains_url { | |
my $url = shift; | |
for my $item (@{ $of_projects }) { | |
return 1 if index($item->{note} // q{}, $url) != -1; | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment