summaryrefslogtreecommitdiff
path: root/web/lib/api/v4/relations.rb
blob: 2d3935b35ea4181681dae7fb38cae4e9f4f836a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# web/lib/api/v4/relations.rb

class Taginfo < Sinatra::Base

    api(4, 'relations/all', {
        :description => 'Information about the different relation types.',
        :parameters => {
            :query => 'Only show results where the relation type matches this query (substring match, optional).'
        },
        :paging => :optional,
        :sort => %w( rtype count ),
        :result => paging_results([
            [:rtype,           :STRING, 'Relation type'],
            [:count,           :INT,    'Number of relations with this type.'],
            [:count_fraction,  :INT,    'Number of relations with this type divided by the overall number of relations.'],
            [:prevalent_roles, :ARRAY,  'Prevalent member roles.', [
                [:role,     :STRING, 'Member role'],
                [:count,    :INT,    'Number of members with this role.'],
                [:fraction, :FLOAT,  'Number of members with this role divided by all members.']
            ]]
        ]),
        :notes => "prevalent_roles can be null if taginfo doesn't have role information for this relation type, or an empty array when there are no roles with more than 1% of members",
        :example => { :page => 1, :rp => 10 },
        :ui => '/relations'
    }) do
        total = @db.count('relation_types').
            condition_if("rtype LIKE ? ESCAPE '@'", like_contains(params[:query])).
            get_first_value().to_i

        res = @db.select('SELECT * FROM relation_types').
            condition_if("rtype LIKE ? ESCAPE '@'", like_contains(params[:query])).
            order_by(@ap.sortname, @ap.sortorder) { |o|
                o.rtype
                o.count
            }.
            paging(@ap).
            execute()

        all_relations = @db.stats('relations').to_i

        prevroles = @db.select('SELECT rtype, role, count, fraction FROM db.prevalent_roles').
            condition("rtype IN (#{ res.map{ |row| "'" + SQLite3::Database.quote(row['rtype']) + "'" }.join(',') })").
            order_by([:count], 'DESC').
            execute()

        pr = {}
        res.each do |row|
            pr[row['rtype']] = []
        end

        prevroles.each do |pv|
            rtype = pv['rtype']
            pv.delete_if{ |k,v| k.is_a?(Integer) || k == 'rtype' }
            pv['count'] = pv['count'].to_i
            pv['fraction'] = pv['fraction'].to_f
            pr[rtype] << pv
        end

        return JSON.generate({
            :page  => @ap.page,
            :rp    => @ap.results_per_page,
            :total => total,
            :url   => request.url,
            :data  => res.map{ |row| {
                :rtype           => row['rtype'],
                :count           => row['count'].to_i,
                :count_fraction  => row['count'].to_f / all_relations,
                :prevalent_roles => row['members_all'] ? pr[row['rtype']][0,10] : nil
            } }
        }, json_opts(params[:format]))
    end

end