-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #29 from unlimitedlabs/journalism_workflow
Journalism workflow
- Loading branch information
Showing
31 changed files
with
1,228 additions
and
6 deletions.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
from pprint import pprint | ||
|
||
import argparse | ||
import os | ||
import sys | ||
|
||
# Set up the standalone Django script | ||
proj_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), | ||
"../") | ||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example_project.settings") | ||
sys.path.append(proj_path) | ||
from django.core.wsgi import get_wsgi_application | ||
application = get_wsgi_application() | ||
|
||
from orchestra.orchestra_api import create_orchestra_project | ||
from orchestra.orchestra_api import get_project_information | ||
|
||
|
||
def main(args): | ||
if args.new: | ||
project_id = create_project() | ||
project_info(project_id) | ||
return | ||
|
||
elif args.status: | ||
project_info(args.project_id) | ||
|
||
elif args.final: | ||
p_info = project_info(args.project_id, verbose=False) | ||
try: | ||
assert p_info['tasks']['copy_editing']['status'] == 'Complete' | ||
pprint(p_info['tasks']['copy_editing']['latest_data']) | ||
except Exception: | ||
print("The '--final' option must be used with a completed project") | ||
sys.exit() | ||
|
||
|
||
def create_project(): | ||
project_id = create_orchestra_project( | ||
None, | ||
'journalism', | ||
'A test run of our journalism workflow', | ||
10, | ||
{ | ||
'article_draft_template': '1F9ULJ_eoJFz1whqjK2thsC6gJup2f35IsUUpbcizcfA' # noqa | ||
}, | ||
'https://docs.google.com/document/d/1s0IJycNAwHtZfsUwyo6lCJ7kI9pTOZddcaiRDdZUSAs', # noqa | ||
'train', | ||
) | ||
print('Project with id {} created!'.format(project_id)) | ||
return project_id | ||
|
||
|
||
def project_info(project_id, verbose=True): | ||
p_info = get_project_information(project_id) | ||
if verbose: | ||
print("Information received! Here's what we got:") | ||
print('') | ||
pprint(p_info) | ||
return p_info | ||
|
||
|
||
if __name__ == '__main__': | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('-p', '--project-id', | ||
help='Existing project id to check status of') | ||
primary_command_group = parser.add_mutually_exclusive_group(required=True) | ||
primary_command_group.add_argument('-n', '--new', action='store_true', | ||
help='Start a new journalism project') | ||
primary_command_group.add_argument('-s', '--status', action='store_true', | ||
help=('Check the status of an ' | ||
'in-progress project')) | ||
primary_command_group.add_argument('-f', '--final', action='store_true', | ||
help=('Output a final summary of the ' | ||
'project')) | ||
args = parser.parse_args() | ||
|
||
if args.new and args.project_id: | ||
print("The '--new' option cannot be used in conjunction with a " | ||
"project id.") | ||
sys.exit() | ||
elif args.status and not args.project_id: | ||
print("The '--status' option must be used in conjunction with a " | ||
"project id.") | ||
sys.exit() | ||
elif args.final and not args.project_id: | ||
print("The '--final' option must be used in conjunction with a " | ||
"project id.") | ||
sys.exit() | ||
|
||
main(args) |
Empty file.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import os | ||
import tempfile | ||
|
||
from django.conf import settings | ||
from PIL import Image | ||
|
||
from orchestra.google_apps.convenience import create_folder_with_permissions | ||
from orchestra.google_apps.convenience import download_file | ||
from orchestra.google_apps.convenience import upload_file | ||
from orchestra.google_apps.permissions import write_with_link_permission | ||
from orchestra.google_apps.service import Service | ||
|
||
import logging | ||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def autoadjust_photos(project_data, prerequisites): | ||
"""Resize all images in a google drive directory.""" | ||
task_data = {} | ||
parent_folder_id = project_data['project_folder_id'] | ||
|
||
# Create a directory to output the photos | ||
output_folder = create_folder_with_permissions( | ||
parent_folder_id, | ||
'Processed Photos', | ||
permissions=[write_with_link_permission], | ||
) | ||
task_data['processed_photo_folder'] = output_folder['id'] | ||
|
||
# List the existing photos | ||
raw_photo_folder_id = (prerequisites | ||
.get('photography') | ||
.get('prerequisites') | ||
.get('article_planning') | ||
.get('prerequisites') | ||
.get('document_creation') | ||
.get('task') | ||
.get('data') | ||
.get('raw_photo_folder')) | ||
service = Service(settings.GOOGLE_P12_PATH, | ||
settings.GOOGLE_SERVICE_EMAIL) | ||
photos_metadata = service.list_folder(raw_photo_folder_id) | ||
|
||
# Iterate over the input photos and process them. | ||
task_data['photos_for_caption'] = [] | ||
for photo_metadata in photos_metadata: | ||
photo, title, mimetype = download_file(photo_metadata) | ||
adjusted_photo_tmpfile = adjust_photo(photo) | ||
upload = upload_file( | ||
task_data['processed_photo_folder'], | ||
adjusted_photo_tmpfile.name, | ||
title, | ||
'image', | ||
mimetype | ||
) | ||
os.unlink(adjusted_photo_tmpfile.name) | ||
embed_link = upload['webContentLink'].replace('&export=download', '') | ||
task_data['photos_for_caption'].append(embed_link) | ||
return task_data | ||
|
||
|
||
def adjust_photo(photo): | ||
|
||
# Write the photo to a temporary file | ||
temp = tempfile.NamedTemporaryFile(mode='wb', delete=False) | ||
temp.write(photo) | ||
|
||
# Open it up and play with it in PIL | ||
im = Image.open(temp.name) | ||
im = im.convert('L') # convert to greyscale | ||
|
||
# Save it back out into a new temporary file | ||
os.unlink(temp.name) | ||
temp2 = tempfile.NamedTemporaryFile(mode='wb', delete=False) | ||
im.save(temp2, format='jpeg') | ||
return temp2 |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
from orchestra.google_apps.convenience import create_document_from_template | ||
from orchestra.google_apps.convenience import create_folder_with_permissions | ||
from orchestra.google_apps.permissions import write_with_link_permission | ||
|
||
import logging | ||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def create_documents(project_data, prerequisites): | ||
"""Create documents and folders needed for the journalism workflow. | ||
The following will be created: | ||
* an 'Article Draft' document where a reporter can draft text. | ||
* a 'Raw Photos' folder where a photographer can upload images. | ||
Documents are created in the project root folder. | ||
""" | ||
task_data = {} | ||
folder_id = project_data['project_folder_id'] | ||
|
||
# Create an Article Draft document. | ||
article_draft_template = project_data['article_draft_template'] | ||
task_data['articleURL'] = create_document_from_template( | ||
article_draft_template, | ||
'Article Draft', | ||
parent_ids=[folder_id], | ||
permissions=[write_with_link_permission], | ||
)['alternateLink'] | ||
|
||
# Create a Raw Photos folder. | ||
task_data['raw_photo_folder'] = create_folder_with_permissions( | ||
folder_id, | ||
'Raw Photos', | ||
permissions=[write_with_link_permission], | ||
)['id'] | ||
|
||
return task_data |
30 changes: 30 additions & 0 deletions
30
journalism_workflow/static/journalism_workflow/copy_editor/js/controllers.js
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
(function () { | ||
'use strict'; | ||
|
||
angular | ||
.module('journalism_workflow.copy_editor.controllers') | ||
.controller('CopyEditorController', CopyEditorController) | ||
|
||
CopyEditorController.$inject = ['$scope', 'orchestraService']; | ||
|
||
function CopyEditorController($scope, orchestraService) { | ||
var vm = $scope; | ||
|
||
// Store the article text document URL for easier summary later | ||
var documentCreationStep = orchestraService.taskUtils.findPrerequisite( | ||
vm.taskAssignment, 'document_creation') | ||
vm.taskAssignment.task.data.articleDocument = documentCreationStep.task.data.articleURL; | ||
|
||
// Set up the photos for captioning | ||
vm.taskAssignment.task.data.photos = []; | ||
var photoAdjustStep = orchestraService.taskUtils.findPrerequisite( | ||
vm.taskAssignment, 'photo_adjustment'); | ||
var photos = photoAdjustStep.task.data.photos_for_caption; | ||
for (var i = 0; i < photos.length; i++) { | ||
vm.taskAssignment.task.data.photos.push({ | ||
src: photos[i], | ||
caption: '' | ||
}); | ||
} | ||
} | ||
})(); |
15 changes: 15 additions & 0 deletions
15
journalism_workflow/static/journalism_workflow/copy_editor/js/directives.js
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
(function () { | ||
'use strict'; | ||
|
||
angular.module('journalism_workflow.copy_editor.directives').directive( | ||
'copyEditor', function() { | ||
return { | ||
restrict: 'E', | ||
controller: 'CopyEditorController', | ||
scope: { | ||
taskAssignment: '=', | ||
}, | ||
templateUrl: '/static/journalism_workflow/copy_editor/partials/copy_editor.html', | ||
}; | ||
}); | ||
})(); |
12 changes: 12 additions & 0 deletions
12
journalism_workflow/static/journalism_workflow/copy_editor/js/modules.js
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
(function () { | ||
'use strict'; | ||
|
||
angular.module('journalism_workflow.copy_editor.module', [ | ||
'journalism_workflow.copy_editor.controllers', | ||
'journalism_workflow.copy_editor.directives' | ||
]); | ||
|
||
angular.module('journalism_workflow.copy_editor.controllers', []); | ||
angular.module('journalism_workflow.copy_editor.directives', []); | ||
|
||
})(); |
63 changes: 63 additions & 0 deletions
63
journalism_workflow/static/journalism_workflow/copy_editor/partials/copy_editor.html
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<section class="section-panel"> | ||
<div class="container-fluid"> | ||
<div class="row section-header"> | ||
<div class="col-lg-12 col-md-12 col-sm-12"> | ||
<h3> | ||
Finalize the article copy | ||
</h3> | ||
</div> | ||
</div> | ||
<div class="row padded"> | ||
<div class="col-lg-12 col-md-12 col-sm-12"> | ||
|
||
<!-- Headline --> | ||
<div class="row padded"> | ||
<div class="col-lg-12 col-md-12 col-sm-12"> | ||
<h3>Write a headline for the article</h3> | ||
</div> | ||
</div> | ||
<div class="row padded"> | ||
<div class="col-lg-12 col-md-12 col-sm-12"> | ||
<form class="form-horizontal text-right"> | ||
<div class="form-group"> | ||
<label for="headlineInput" class="col-sm-1 col-md-1 col-lg-1 control-label text-right">Headline</label> | ||
<div class="col-sm-11 col-md-11 col-lg-11"> | ||
<input type="text" class="form-control" id="headlineInput" placeholder="Headline for the story" ng-model="taskAssignment.task.data.headline"> | ||
</div> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
|
||
<!-- Photo Captions --> | ||
<div class="row padded"> | ||
<div class="col-lg-12 col-md-12 col-sm-12"> | ||
<h3>Caption the photos taken for the article</h3> | ||
</div> | ||
</div> | ||
<div class="row padded"> | ||
<div ng-repeat="img in taskAssignment.task.data.photos"> | ||
<div class="col-sm-6 col-md-4"> | ||
<div class="thumbnail"> | ||
<a href="{{img.src}}" target="_blank"> | ||
<img src="{{img.src}}" alt="Processed Image"> | ||
</a> | ||
<div class="caption text-center"> | ||
<h3>Caption</h3> | ||
<form class="form-horizontal"> | ||
<div class="form-group"> | ||
<div class="col-sm-12"> | ||
<input type="text" class="form-control" placeholder="Caption for the photo" ng-model="img.caption"/> | ||
</div> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
</div> | ||
</div> | ||
</div> | ||
</div> |
13 changes: 13 additions & 0 deletions
13
journalism_workflow/static/journalism_workflow/editor/js/controllers.js
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
(function () { | ||
'use strict'; | ||
|
||
angular | ||
.module('journalism_workflow.editor.controllers') | ||
.controller('StoryFormController', StoryFormController) | ||
|
||
StoryFormController.$inject = ['$scope', 'orchestraService']; | ||
|
||
function StoryFormController($scope, orchestraService) { | ||
var vm = $scope; | ||
} | ||
})(); |
15 changes: 15 additions & 0 deletions
15
journalism_workflow/static/journalism_workflow/editor/js/directives.js
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
(function () { | ||
'use strict'; | ||
|
||
angular.module('journalism_workflow.editor.directives').directive( | ||
'editor', function() { | ||
return { | ||
restrict: 'E', | ||
controller: 'StoryFormController', | ||
scope: { | ||
taskAssignment: '=', | ||
}, | ||
templateUrl: '/static/journalism_workflow/editor/partials/editor.html', | ||
}; | ||
}); | ||
})(); |
12 changes: 12 additions & 0 deletions
12
journalism_workflow/static/journalism_workflow/editor/js/modules.js
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
(function () { | ||
'use strict'; | ||
|
||
angular.module('journalism_workflow.editor.module', [ | ||
'journalism_workflow.editor.controllers', | ||
'journalism_workflow.editor.directives' | ||
]); | ||
|
||
angular.module('journalism_workflow.editor.controllers', []); | ||
angular.module('journalism_workflow.editor.directives', []); | ||
|
||
})(); |
Oops, something went wrong.