Skip to content
This repository was archived by the owner on Sep 26, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
b02d912
merge conflict split-subjects script
nonword Oct 26, 2015
0207dab
adding full set of emigrant subjects
nonword Oct 26, 2015
b9905d3
merge conflix
nonword Oct 27, 2015
e9071e8
merging new 4-way split subjects
nonword Oct 27, 2015
f7cfc2d
Merge branch 'master' into emigrant-production
nonword Oct 27, 2015
132747b
Merge branch 'master' into emigrant-production
nonword Oct 27, 2015
2de6219
trivial change
nonword Oct 27, 2015
c99244e
trivial change
nonword Oct 27, 2015
724f478
Merge branch 'master' into emigrant-production
nonword Oct 29, 2015
47290dd
adding complete set of four-way cut subjects
nonword Oct 29, 2015
97a944d
Merge branch 'master' into emigrant-production
nonword Oct 29, 2015
d36988e
Merge branch 'master' into emigrant-production
nonword Oct 29, 2015
206478f
Merge branch 'master' into emigrant-production
nonword Oct 30, 2015
967dc2d
Merge branch 'emigrant-workflow-tweaks' into emigrant-production
nonword Nov 2, 2015
f40e852
Merge branch 'master' into emigrant-production
nonword Nov 3, 2015
4e84680
Merge branch 'master' into emigrant-production
nonword Nov 3, 2015
c3b27e4
Merge branch 'emigrant-launch-fixes' into emigrant-production
nonword Nov 5, 2015
5336fa9
changing workflow.retire_limit to be a percentage to match the implem…
nonword Nov 10, 2015
bf702ef
Merge branch 'master' into emigrant-production
nonword Nov 10, 2015
f3d4b05
Merge branch 'admin-dashboard-update' into emigrant-production
nonword Nov 11, 2015
cb9a8df
Merge branch 'retire-limit-should-be-percentage' into emigrant-produc…
nonword Nov 11, 2015
c394ab1
Merge branch 'verify-fixes' into emigrant-production
nonword Nov 11, 2015
7a0a48c
tutorial complete not evaluated correctly causing it to always appear…
nonword Nov 11, 2015
2a13d54
Merge branch 'tutorial-complete-bug' into emigrant-production
nonword Nov 11, 2015
3f9b0d3
Merge branch 'verify-fixes' into emigrant-production
nonword Nov 11, 2015
19c4850
Merge branch 'verify-fixes' into emigrant-production
nonword Nov 11, 2015
1f75369
Merge branch 'admin-dashboard-update' into emigrant-production
nonword Nov 11, 2015
c1e6fa8
Merge branch 'admin-dashboard-update' into emigrant-production
nonword Nov 11, 2015
1423870
reverting classifying_user_ids check when calling retire!, but with a…
nonword Nov 12, 2015
bf75009
Updates to Emigrants copy.
wlla Nov 20, 2015
86020a8
Updates to emigrantscopy.
wlla Nov 20, 2015
3280364
Updates to copy.
wlla Nov 27, 2015
0b029d7
Merge branch 'master' into copyemigrants
wlla Nov 27, 2015
7aed8b9
Merge branch 'verify-fixes' into emigrant-production
nonword Nov 27, 2015
f2891eb
Tutorial updates.
wlla Nov 27, 2015
6c0b2ec
Merge branch 'emigrant-production' into copyemigrants
wlla Nov 27, 2015
3ca900c
Merge branch 'copyemigrants' into emigrant-production
nonword Nov 27, 2015
1cbabf7
Copy Overhaul.
wlla Nov 27, 2015
b4addf9
fix tutorial video heights, update tutorial copy
beefoo Nov 27, 2015
61b80c3
Fixed help line breaks.
wlla Nov 27, 2015
9516ebe
Merge branch 'copyemigrants' into emigrant-production
nonword Nov 27, 2015
fc88a67
Merge branch 'verify-fixes' into emigrant-production
nonword Nov 27, 2015
fae2b93
selective merge from green-books transcribe frontend changes to suppo…
nonword Jan 11, 2016
91fff26
making edit button in verify workflow configurable; better visual tre…
nonword Jan 12, 2016
8c1cf2a
rough impl of bot interface, final data export, dupe classification p…
nonword Jan 12, 2016
7ff58fc
Adding a mess of new stuff including: final_* models and serializers …
nonword Jan 29, 2016
25dec53
Merge branch 'verify-transcribe-traversal' into emigrant-production
nonword Feb 1, 2016
e2d542a
Merge branch 'retire-limit-should-be-percentage' into emigrant-produc…
nonword Feb 1, 2016
35c6436
merge bots-and-data-export into emigrant-production
nonword Feb 1, 2016
c954791
bunch of mostly backend changes including revisions to collect-unique…
nonword Feb 1, 2016
5811864
missing nomoresubjectsmodal component
nonword Feb 2, 2016
e2a3311
workflow.subjects_editable should default to false
nonword Feb 2, 2016
b1bf3bb
fixes
nonword Feb 2, 2016
8dd2a3a
better loading indicator in verify
nonword Mar 4, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ gem 'omniauth-facebook'
gem "omniauth-google-oauth2"
gem 'omniauth-zooniverse', '~> 0.0.3'

gem 'mongoid', '~> 4.0.2'
gem 'mongoid' # , '~> 4.0.2'
gem 'active_model_serializers'
gem 'mongoid-serializer'
gem 'rack-cors', :require => 'rack/cors'
Expand All @@ -38,6 +38,8 @@ gem 'puma', '~> 2.14.0'

gem 'logstasher', '~> 0.6'

# gem 'mongoid_fulltext'

group :development do
gem 'dotenv-rails'
end
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ DEPENDENCIES
kaminari
launchy
logstasher (~> 0.6)
mongoid (~> 4.0.2)
mongoid
mongoid-rspec (>= 1.6.0)!
mongoid-serializer
moped
Expand Down
Binary file added app/assets/images/checkmark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions app/assets/javascripts/components/app-router.cjsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Verify = require './verify'
# TODO Group routes currently not implemented
GroupPage = require './group-page'
GroupBrowser = require './group-browser'
FinalSubjectSetBrowser = require './final-subject-set-browser'
FinalSubjectSetPage = require './final-subject-set-page'

Project = require 'models/project.coffee'

Expand Down Expand Up @@ -74,6 +76,20 @@ class AppRouter
name={workflow.name + '_entire_page'}
/>
}

<Route
path='data/exports'
handler={FinalSubjectSetBrowser}
name='final_subject_sets'
/>
{ if project.downloadable_data
<Route
path='data/exports/:final_subject_set_id'
handler={FinalSubjectSetPage}
name='final_subject_set_page'
/>
}

{ # Project-configured pages:
project.pages?.map (page, key) =>
<Route
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/components/app.cjsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ App = React.createClass
error: "Having trouble logging you in"

setTutorialComplete: ->
previously_saved = @state.user?.tutorial_complete?
previously_saved = @state.user?.tutorial_complete

# Immediately ammend user object with tutorial_complete flag so that we can hide the Tutorial:
@setState user: $.extend(@state.user ? {}, tutorial_complete: true)
Expand Down
156 changes: 156 additions & 0 deletions app/assets/javascripts/components/final-subject-set-browser.cjsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
React = require 'react'
{Navigation} = require 'react-router'
API = require '../lib/api'
Project = require 'models/project.coffee'
GenericButton = require('components/buttons/generic-button')

module.exports = React.createClass
displayName: 'FinalSubjectSetBrowser'

mixins: [Navigation]

getInitialState:->
entered_keyword: @props.query.keyword
searched_keyword: null
fetching_keyword: null
current_page: 1
more_pages: false
results: []
project: null

componentDidMount: ->
@checkKeyword()

API.type('projects').get().then (result)=>
@setState project: new Project(result[0])

componentWillReceiveProps: (new_props) ->
@checkKeyword new_props

checkKeyword: (props = @props) ->
if props.query.keyword
@fetch props.query.keyword

fetch: (keyword, page = 1) ->
return if ! @isMounted()

if keyword != @state.fetching_keyword

results = @state.results
results = [] if @state.searched_keyword != keyword
@setState fetching_keyword: keyword, fetching_page: page, results: results, () =>
per_page = 20
params =
keyword: keyword
per_page: per_page
page: @state.fetching_page

API.type('final_subject_sets').get(params).then (sets) =>
results = @state.results
offset = (@state.fetching_page-1) * per_page
for s,i in sets
results[i + offset] = s
@setState
results: results
searched_keyword: @props.query.keyword
current_page: @state.fetching_page
fetching_keyword: null
fetching_page: null
more_pages: sets?[0]?.getMeta('next_page')

handleKeyPress: (e) ->
if @isMounted()

if [13].indexOf(e.keyCode) >= 0 # ENTER:
@search e.target.value

search: (keyword) ->
keyword = @refs.search_input?.getDOMNode().value.trim() unless keyword?

@transitionTo "final_subject_sets", null, {keyword: keyword}

loadMore: ->
@fetch @state.searched_keyword, @state.current_page + 1

handleChange: (e) ->
@setState entered_keyword: e.target.value

render: ->
return null if ! @state.project?

<div className="page-content final-subject-set-browser">

{ if ! @state.project.downloadable_data
<div>
<h3>Data Exports Not Available</h3>
<p>Sorry, but public data exports are not enabled for this project yet.</p>
</div>

else
<div>
<a className="standard-button json-link" href="/data/latest" target="_blank">Download Latest Raw Data</a>
<a className="standard-button json-link" href="/data.atom" target="_blank" title="ATOM Feed of Data Releases"><i className="fa fa-rss-square"></i></a>

<h2>Data Exports</h2>

{ if ! @state.searched_keyword
<div>
<h3>Download</h3>

<p>Participants have made {@state.project.classification_count.toLocaleString()} contributions to {@state.project.title} to date. This project periodically builds a merged, anonymized dump of that data, which is made public here.</p>

<p>You can download the latest using the button in the upper-right. For help interpretting the data, see <a href="https://github.com/zooniverse/scribeAPI/wiki/Data-Exports" target="_blank">Scribe WIKI on Data Exports</a>.</p>

<h3>Browse</h3>

<p>Preview the data by searching by keyword below:</p>
</div>
}

<form>
<input id="data-search" type="text" placeholder="Enter keyword" ref="search-input" value={@state.entered_keyword} onChange={@handleChange} onKeyDown={@handleKeyPress} />
<input className="standard-button" type="submit" value="Search" onclick={@search} />
</form>

{ if @state.searched_keyword && @state.results.length == 0
<p>No matches yet for "{@state.searched_keyword}"</p>

else if @state.results.length > 0
<div>
<p>Found {@state.results[0].getMeta('total')} matches</p>
<ul className="results">
{ for set in @state.results
url = "/#/data/exports/#{set.id}?keyword=#{@state.searched_keyword}"
matches = []
safe_keyword = (w.replace(/\W/g, "\\$&") for w in @state.searched_keyword.toLowerCase().replace(/"/g,'').split(' ')).join("|")
regex = new RegExp("(#{safe_keyword})", 'gi')
for k of set.search_terms_by_field
matches.push(field: k, term: v) for v in set.search_terms_by_field[k] when v.match(regex)
<li key={set.id}>
<div className="image">
<a href={url}>
<img src={set.subjects[0].location.thumbnail} />
</a>
</div>
<div className="matches">
{ for m,i in matches[0...2]
<div key={i} className="match">
<a href={url}>
<span className="field">{m.field}</span>
<span className="term" dangerouslySetInnerHTML={{__html: m.term.truncate(100).replace(regex, "<em>$1</em>")}} />
</a>
</div>
}
</div>
</li>
}
</ul>
{ if @state.more_pages
<GenericButton className="load-more" onClick={@loadMore} label="More" />
}
</div>
}
</div>
}
</div>

79 changes: 79 additions & 0 deletions app/assets/javascripts/components/final-subject-set-page.cjsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
React = require 'react'
API = require '../lib/api'

GenericButton = require('components/buttons/generic-button')

module.exports = React.createClass
displayName: 'FinalSubjectSetPage'

getInitialState:->
set: null

componentDidMount: ->
API.type("final_subject_sets").get(@props.params.final_subject_set_id).then (set) =>
@setState
set: set

render: ->
return null if ! @state.set

<div className="page-content final-subject-set-browser">
<div className="final-subject-set-page">
<a className="standard-button json-link" href="/final_subject_sets/#{@state.set.id}.json" target="_blank">Download Raw Data</a>
<h2>Set {@state.set.id}</h2>

<ul>
{ for subject in @state.set.subjects
<li className="final-subject-set" key={subject.id}>
<img src={subject.location.standard} className="standard-image"/>
<ul>
{
assertions = subject.assertions.sort (a1,a2) ->
if a1.region.y < a2.region.y
-1
else
1
null
}
{ for assertion,i in assertions when assertion.name
<li key={i}>
<h3>{assertion.name}</h3>

<ul className="assertion-data">
{ for k of assertion.data
console.log "assertion data: ", k, assertion.data
<li key={k}>
<span className="value">{assertion.data[k]}</span>
{ if k != 'value'
<span className="data-key">({k.replace /_/g, ' '})</span>
}
</li>
}
</ul>
<dl className="assertion-properties">
<dt>Confidence</dt>
<dd>{Math.round(100 * assertion.confidence)}%</dd>
<dt>Status</dt>
<dd>{assertion.status.replace /_/, ' '}</dd>
<dt>Distinct Classifications</dt>
<dd>{assertion.classifications?.length || 0}</dd>
</dl>
{
viewer_width = assertion.region.width
scale = viewer_width / assertion.region.width
s =
background: "url(#{subject.location.standard}) no-repeat -#{Math.round(assertion.region.x * scale)}px -#{Math.round(assertion.region.y * scale)}px"
width: viewer_width + 'px'
height: Math.round(assertion.region.height * scale) + 'px'
<div className="image-crop" src={subject.location.standard} style={s} />
}
</li>
}
</ul>

</li>
}
</ul>
</div>
</div>

13 changes: 7 additions & 6 deletions app/assets/javascripts/components/mark/index.cjsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ HideOtherMarksButton = require 'components/buttons/hide-other-marks-button'
DraggableModal = require 'components/draggable-modal'
Draggable = require 'lib/draggable'
{Link} = require 'react-router'
NoMoreSubjectsModal = require 'components/no-more-subjects-modal'

module.exports = React.createClass # rename to Classifier
displayName: 'Mark'
Expand Down Expand Up @@ -175,7 +176,7 @@ module.exports = React.createClass # rename to Classifier
activeSubjectHelper: null

render: ->
return null unless @getCurrentSubjectSet()? && @getActiveWorkflow()?
return null unless @getActiveWorkflow()?

currentTask = @getCurrentTask()
TaskComponent = @getCurrentTool()
Expand All @@ -184,9 +185,6 @@ module.exports = React.createClass # rename to Classifier
onFirstAnnotation = @state.taskKey == firstTask
currentSubtool = if @state.currentSubtool then @state.currentSubtool else @getTasks()[firstTask]?.tool_config.tools?[0]

# direct link to this page
pageURL = "#{location.origin}/#/mark?subject_set_id=#{@getCurrentSubjectSet().id}&selected_subject_id=#{@getCurrentSubject()?.id}"


if currentTask?.tool is 'pick_one'
currentAnswer = (a for a in currentTask.tool_config.options when a.value == currentAnnotation.value)[0]
Expand All @@ -196,13 +194,16 @@ module.exports = React.createClass # rename to Classifier

<div className="subject-area">
{ if @state.noMoreSubjectSets
style = marginTop: "50px"
<p style={style}>There is nothing left to do. Thanks for your work and please check back soon!</p>
<NoMoreSubjectsModal header="Nothing more to mark" workflowName={@props.workflowName} project={@props.project} />

else if @state.notice
<DraggableModal header={@state.notice.header} onDone={@state.notice.onClick}>{@state.notice.message}</DraggableModal>

else if @getCurrentSubjectSet()?

# direct link to this page
pageURL = "#{location.origin}/#/mark?subject_set_id=#{@getCurrentSubjectSet().id}&selected_subject_id=#{@getCurrentSubject()?.id}"

<SubjectSetViewer
subject_set={@getCurrentSubjectSet()}
subject_index={@state.subject_index}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ module.exports = React.createClass
classes.push 'transcribable' if @props.isTranscribable
classes.push 'interim' if @props.interim
classes.push if @props.disabled then 'committed' else 'uncommitted'
classes.push "tanscribing" if @checkLocation()
classes.push "tanscribing" if @inTranscribeWorkflow()

x1 = @props.mark.x
width = @props.mark.width
Expand Down
33 changes: 33 additions & 0 deletions app/assets/javascripts/components/no-more-subjects-modal.cjsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
React = require 'react'
DraggableModal = require 'components/draggable-modal'
GenericButton = require 'components/buttons/generic-button'

module.exports = React.createClass
displayName: 'NoMoreSubjectsModal'

getDefaultProps: ->
header: 'Nothing more to do here'

propTypes:
project: React.PropTypes.object.isRequired
header: React.PropTypes.string.isRequired
workflowName: React.PropTypes.string.isRequired

render: ->
next_workflow = @props.project.workflowWithMostActives @props.workflowName
next_href = "/"
if next_workflow?
next_href = "/#/" + next_workflow.name

<DraggableModal
header = {@props.header}
buttons = {<GenericButton label='Continue' href={next_href} />}
>
Currently, there are no {@props.project.term('subject')}s for you to {@props.workflowName}.
{ if next_workflow?
<span> Try <a href={next_href}>{next_workflow.name.capitalize()}</a> instead!</span>
else
<span> Looks like there's no work do do right now. Please come back later.</span>
}
</DraggableModal>

Loading