• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

benwbrum / fromthepage / 18198125262

02 Oct 2025 03:43PM UTC coverage: 65.028%. Remained the same
18198125262

push

github

web-flow
Rubocop lint remove array whitespaces (#4950)

1848 of 3359 branches covered (55.02%)

Branch coverage included in aggregate %.

154 of 201 new or added lines in 62 files covered. (76.62%)

8087 of 11919 relevant lines covered (67.85%)

109.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

51.94
/app/controllers/display_controller.rb
1
class DisplayController < ApplicationController
1✔
2
  include ApplicationHelper
1✔
3
  public :render_to_string
1✔
4

5
  protect_from_forgery except: [:set_note_body]
1✔
6

7
  PAGES_PER_SCREEN = 5
1✔
8

9
  def read_work
1✔
10
    if params.has_key?(:work_id)
71✔
11
      @work = Work.friendly.find(params[:work_id])
71!
12
    elsif params.has_key?(:id)
×
13
      @work = Work.friendly.find(params[:id])
×
14
    elsif params.has_key?(:url)
×
15
      @work = Work.find_by_id(params[:url][:work_id])
×
16
    end
17
    if params.has_key?(:needs_review)
71✔
18
      @review = params[:needs_review]
10✔
19
    end
20

21
    # Handle page range parameter
22
    if params.has_key?(:page_range)
71✔
23
      @page_range = parse_page_range(params[:page_range])
5✔
24
      if @page_range
5✔
25
        @start_page, @end_page = @page_range
4✔
26
        @page_range_filter = true
4✔
27
      end
28
    end
29

30
    @total = @work.pages.count
71✔
31
    if @article
71✔
32
      # restrict to pages that include that subject
×
33
      redirect_to action: 'read_all_works', article_id: @article.id, page: 1 and return
×
34
    else
35
      # Apply page range filter if specified
71✔
36
      base_pages = @page_range_filter ? @work.pages.where(position: @start_page..@end_page) : @work.pages
71✔
37

38
      if @review == 'review'
71✔
39
        @pages = base_pages.review.order('position').paginate(page: params[:page], per_page: PAGES_PER_SCREEN)
3✔
40
        @count = @pages.count
3✔
41
        @heading = @page_range_filter ? "#{t('.pages_need_review')} (#{@start_page}-#{@end_page})" : t('.pages_need_review')
3✔
42
      elsif @review == 'incomplete'
68!
43
        @pages = base_pages.incomplete.order('position').paginate(page: params[:page], per_page: PAGES_PER_SCREEN)
×
44
        @count = @pages.count
×
45
        @heading = @page_range_filter ? "#{t('.pages_need_completion')} (#{@start_page}-#{@end_page})" : t('.pages_need_completion')
×
46
      elsif @review == 'transcription'
68✔
47
        @pages = base_pages.needs_transcription.order('position').paginate(page: params[:page], per_page: PAGES_PER_SCREEN)
1✔
48
        @count = @pages.count
1✔
49
        @incomplete_pages = base_pages.needs_completion.order('position').paginate(page: params[:page], per_page: PAGES_PER_SCREEN)
1✔
50
        @incomplete_count = @incomplete_pages.count
1✔
51
        @heading = @page_range_filter ? "#{t('.pages_need_transcription')} (#{@start_page}-#{@end_page})" : t('.pages_need_transcription')
1!
52
      elsif @review == 'index'
67!
53
        @pages = base_pages.needs_index.order('position').paginate(page: params[:page], per_page: PAGES_PER_SCREEN)
×
54
        @count = @pages.count
×
55
        @heading = @page_range_filter ? "#{t('.pages_need_indexing')} (#{@start_page}-#{@end_page})" : t('.pages_need_indexing')
×
56
      elsif @review == 'translation'
67✔
57
        @pages = base_pages.needs_translation.order('position').paginate(page: params[:page], per_page: PAGES_PER_SCREEN)
1✔
58
        @count = @pages.count
1✔
59
        @heading = @page_range_filter ? "#{t('.pages_need_translation')} (#{@start_page}-#{@end_page})" : t('.pages_need_translation')
1!
60
      elsif @review == 'translation_review'
66✔
61
        @pages = base_pages.translation_review.paginate(page: params[:page], per_page: PAGES_PER_SCREEN)
2✔
62
        @count = @pages.count
2✔
63
        @heading = @page_range_filter ? "#{t('.translations_need_review')} (#{@start_page}-#{@end_page})" : t('.translations_need_review')
2!
64
      elsif @review == 'translation_index'
64!
65
        @pages = base_pages.needs_translation_index.paginate(page: params[:page], per_page: PAGES_PER_SCREEN)
×
66
        @count = @pages.count
×
67
        @heading = @page_range_filter ? "#{t('.translations_need_indexing')} (#{@start_page}-#{@end_page})" : t('.translations_need_indexing')
×
68
      else
64✔
69
        @pages = base_pages.paginate(page: params[:page], per_page: PAGES_PER_SCREEN)
64✔
70
        @count = @pages.count
64✔
71
        @heading = @page_range_filter ? "#{t('.pages')} (#{@start_page}-#{@end_page})" : t('.pages')
64✔
72
      end
73
    end
74
    session[:col_id] = @collection.slug
71✔
75
  end
76

77
  def read_all_works
1✔
78
    if @article
1✔
79
      # restrict to pages that include that subject
1✔
80
      @pages = Page.order('work_id, position').joins('INNER JOIN page_article_links pal ON pages.id = pal.page_id').where(['pal.article_id = ?', @article.id]).where(work_id: @collection.works.ids).paginate(page: params[:page], per_page: PAGES_PER_SCREEN)
1✔
81
      @pages.distinct!
1✔
82
      @heading = t('.pages_that_mention', article: @article.title)
1✔
83
    else
×
84
      @pages = Page.paginate :all, page: params[:page],
×
85
                                        order: 'work_id, position',
86
                                        per_page: 5
87
      @heading = t('.pages')
×
88
    end
89
    session[:col_id] = @collection.slug
1✔
90
  end
91

92
  def display_page
1✔
93
    # Set meta information for web crawlers and archival only for pages with content
94
    if @page.status != 'new'
77✔
95
      @page_title = "#{@page.title || "Page #{@page.position}"} - #{@work.title} - #{@collection.title}"
58✔
96
      @meta_description = "Transcript of #{@page.title || "page #{@page.position}"} from #{@work.title} in the #{@collection.title} collection."
58✔
97
      @meta_keywords = [@work.title, @collection.title, @page.title, 'transcript', 'transcription', 'historical document'].compact.join(', ')
58✔
98

99
      # Generate structured data for better content understanding
100
      @structured_data = {
101
        '@context' => 'https://schema.org',
58✔
102
        '@type' => 'DigitalDocument',
103
        'name' => @page.title || "Page #{@page.position}",
104
        'description' => @meta_description,
105
        'text' => @page.verbatim_transcription_plaintext,
106
        'inLanguage' => @collection.text_language || 'en',
107
        'isPartOf' => {
108
          '@type' => 'Book',
109
          'name' => @work.title,
110
          'author' => @work.author,
111
          'dateCreated' => @work.document_date,
112
          'isPartOf' => {
113
            '@type' => 'Collection',
114
            'name' => @collection.title,
115
            'description' => to_snippet(@collection.intro_block)
116
          }
117
        },
118
        'url' => request.original_url,
119
        'dateModified' => @page.updated_at&.iso8601,
58!
120
        'publisher' => {
121
          '@type' => 'Organization',
122
          'name' => @collection.owner&.display_name || 'FromThePage'
58!
123
        }
124
      }
125

126
      # Add archival-friendly meta tags
127
      respond_to do |format|
58✔
128
        format.html do
58✔
129
          # Additional headers for better archival
130
          response.headers['X-Robots-Tag'] = 'index, follow, archive'
58✔
131
        end
132
      end
133
    end
134
  end
135

136
  def paged_search
1✔
137
    if @article
×
138
      render plain: 'This functionality has been disabled.  Please contact support@frothepage.com if you need it.'
×
139
      return
×
140

141
      session[:col_id] = @collection.slug
×
142
      # get the unique search terms
143
      terms = []
×
144
      @search_string = ''
×
145
      @article.page_article_links.each do |link|
×
146
        terms << link.display_text.gsub(/\s+/, ' ')
×
147
      end
148
      terms.uniq!
×
149
      # process them for display and search
150
      terms.each do |term|
×
151
        # don't add required text
152
        if term.match(/ /)
×
153
          @search_string += "\"#{term}\" "
×
154
        else
×
155
          @search_string += term + '* '
×
156
        end
157
      end
158
      if params[:unlinked_only]
×
159
        conditions =
NEW
160
          ['MATCH(search_text) AGAINST(? IN BOOLEAN MODE)'+
×
161
          ' AND pages.id not in '+
162
          '    (SELECT page_id FROM page_article_links WHERE article_id = ?)',
163
          @search_string,
164
          @article.id]
165

166
      else
×
167
        conditions =
NEW
168
          ['MATCH(search_text) AGAINST(? IN BOOLEAN MODE)',
×
169
          @search_string]
170
      end
171
      @pages = Page.order('work_id, position').joins(:work).where(work_id: @collection.works.ids).where(conditions).paginate(page: params[:page])
×
172
    else
×
173
      @search_attempt = SearchAttempt.find_by(slug: params[:id])
×
174
      session[:search_attempt_id] = @search_attempt.id if session[:search_attempt_id] != @search_attempt.id
×
175

176
      # restrict to pages that include that subject
177
      @collection = @search_attempt.collection || @search_attempt.document_set || @search_attempt.work.collection
×
178
      @work = @search_attempt&.work
×
179
      if ELASTIC_ENABLED
×
180
        search_mode = nil
×
181
        search_slug = nil
×
182

183
        if @search_attempt.search_type == 'collection'
×
184
          if @search_attempt.collection.present?
×
185
            search_mode = 'collection'
×
186
            search_slug = @search_attempt.collection.slug
×
187
          elsif @search_attempt.document_set.present?
×
188
            search_mode = 'docset'
×
189
            search_slug = @search_attempt.document_set.slug
×
190
          end
×
191
        elsif @search_attempt.search_type == 'work'
×
192
          if @search_attempt.work.present?
×
193
            search_mode = 'work'
×
194
            search_slug = @search_attempt.work.slug
×
195
          end
196
        end
197

198
        # TODO: Need metrics tracking from new_landing search
199
        # Redirect to "findaproject" tabbed search results
200
        redirect_to controller: 'dashboard',
×
201
                    action: 'landing_page',
202
                    search: @search_attempt.query,
203
                    mode: search_mode,
204
                    slug: search_slug
205
      else
×
206
        pages = @search_attempt.query_results
×
207
        @pages = pages.paginate(page: params[:page])
×
208
      end
209
      @search_string = params[:id].split('-')[0...-1].join(' ')
×
210
    end
211
    logger.debug "DEBUG #{@search_string}"
×
212
  end
213

214
  private
1✔
215

216
  # Parse page range from parameter like "5-7", "pp5-7", "p5-7"
217
  def parse_page_range(range_param)
1✔
218
    return nil if range_param.blank?
16✔
219

220
    # Remove optional "pp" or "p" prefix and extract numbers
221
    clean_range = range_param.gsub(/^pp?/, '')
14✔
222

223
    # Match pattern like "5-7"
224
    if match = clean_range.match(/^(\d+)-(\d+)$/)
14✔
225
      start_page = match[1].to_i
12✔
226
      end_page = match[2].to_i
12✔
227

228
      # Validate that start is less than or equal to end
229
      return nil if start_page > end_page || start_page < 1
12✔
230

231
      [start_page, end_page]
9✔
232
    else
233
      nil
234
    end
235
  end
236
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc