GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#10)
by
unknown
01:56
created

SearchJobsController.index()   F

Complexity

Conditions 9

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 9
Bugs 1 Features 0
Metric Value
cc 9
c 9
b 1
f 0
dl 0
loc 39
rs 3
1
# -*- coding: utf-8 -*-
2
import json
3
import logging
4
from elasticsearch_dsl import Q, SF
5
6
from sqlalchemy.orm.exc import NoResultFound
7
from tg.decorators import expose, redirect, paginate
8
from tg.exceptions import HTTPNotFound
9
10
from pyjobsweb.model import JobAlchemy
11
from pyjobsweb.model import JobElastic
12
from pyjobsweb.model.data import SOURCES
13
from pyjobsweb.lib.base import BaseController
14
from pyjobsweb.lib.elasticsearch_ import PaginatedSearch
15
from pyjobsweb.forms.research_forms import JobsResearchForm
16
17
18
class SearchJobsController(BaseController):
19
    items_per_page = 10
20
21
    def __init__(self, items_per_page=10):
22
        self.items_per_page = items_per_page
23
24
    @staticmethod
25
    def _compute_keyword_queries(terms):
26
        search_on = dict(
27
            description=[
28
                'description',
29
                'description.technologies'
30
            ],
31
            title=[
32
                'title',
33
                'title.technologies'
34
             ],
35
            company=['company']
36
        )
37
38
        description_query = Q(
39
            'multi_match',
40
            type='most_fields',
41
            query=terms,
42
            fields=search_on['description'],
43
            fuzziness='AUTO',
44
            operator='or',
45
            minimum_should_match='1<2 2<2 3<3 4<3 5<4 6<5 7<5 8<6 9<6',
46
            boost=len(terms.split(','))
47
        )
48
49
        title_query = Q(
50
            'multi_match',
51
            type='most_fields',
52
            query=terms,
53
            fields=search_on['title'],
54
            fuzziness='AUTO',
55
            operator='or',
56
            minimum_should_match='1<1',
57
            boost=20 - len(terms.split(',')) + 1
58
        )
59
60
        company_name_query = Q(
61
            'multi_match',
62
            type='best_fields',
63
            query=terms,
64
            fields=search_on['company'],
65
            fuzziness='AUTO',
66
            operator='or',
67
            minimum_should_match='1<1',
68
            boost=50
69
        )
70
71
        keyword_queries = Q(
72
            'bool',
73
            must=[
74
                company_name_query
75
            ],
76
            should=[
77
                title_query,
78
                description_query
79
            ]
80
        ) | Q(
81
            'bool',
82
            must=[
83
                description_query
84
            ],
85
            should=[
86
                title_query,
87
                company_name_query
88
            ]
89
        )
90
        return keyword_queries
91
92
    @staticmethod
93
    def _compute_decay_functions():
94
        decay_function = SF(
95
            'gauss',
96
            publication_datetime=dict(
97
                origin='now',
98
                scale='30d',
99
                offset='7d',
100
                decay='0.1'
101
            )
102
        )
103
104
        return [decay_function]
105
106
    @staticmethod
107
    def _apply_geolocation_filters(query, (lat, lon), radius):
108
        query = query.filter(
109
            'geo_distance',
110
            geolocation=[lon, lat],
111
            distance='%skm' % float(radius)
112
        )
113
114
        query = query.filter(
115
            'term',
116
            geolocation_is_valid=True
117
        )
118
119
        return query
120
121
    @staticmethod
122
    def _apply_date_sort(query):
123
        query = query.sort(
124
            '-publication_datetime',
125
            '-_score'
126
        )
127
128
        return query
129
130
    @expose('pyjobsweb.templates.jobs.list')
131
    @paginate('jobs', items_per_page=items_per_page)
132
    def index(self, query=None, radius=None, center=None, sort_by=None,
133
              *args, **kwargs):
134
        if not query and not radius and not center:
135
            redirect('/jobs')
136
137
        search_query = JobElastic().search()
138
139
        if query:
140
            keyword_queries = self._compute_keyword_queries(query)
141
            decay_functions = self._compute_decay_functions()
142
143
            search_query.query = Q(
144
                'function_score',
145
                query=keyword_queries,
146
                functions=decay_functions
147
            )
148
149
        try:
150
            geoloc_query = json.loads(center)
151
            coordinates = geoloc_query['coordinates']
152
            lat, lon = (coordinates['lat'], coordinates['lon'])
153
        except (ValueError, TypeError):
154
            # One of the following case has occurred:
155
            #     - Center wasn't a valid json string
156
            #     - Radius couldn't be converted to float
157
            # Since both these information are required to set a geolocation
158
            # filter are required, we ignore it.
159
            pass
160
        else:
161
            search_query = self._apply_geolocation_filters(
162
                search_query, (lat, lon), radius if radius else 5.0)
163
164
        if sort_by == 'dates':
165
            search_query = self._apply_date_sort(search_query)
166
167
        return dict(sources=SOURCES, jobs=PaginatedSearch(search_query),
168
                    job_offer_search_form=JobsResearchForm)
169
170
171
class JobsController(BaseController):
172
    items_per_page = 10
173
    search = SearchJobsController(items_per_page)
174
175
    @expose('pyjobsweb.templates.jobs.list')
176
    @paginate('jobs', items_per_page=items_per_page)
177
    def index(self, *args, **kwargs):
178
        try:
179
            job_offers = JobAlchemy.get_all_job_offers()
180
        except NoResultFound:
181
            job_offers = None
182
183
        return dict(sources=SOURCES, jobs=job_offers,
184
                    job_offer_search_form=JobsResearchForm)
185
186
    @expose('pyjobsweb.templates.jobs.details')
187
    def details(self, offer_id, *args, **kwargs):
188
        try:
189
            job = JobAlchemy.get_job_offer(offer_id)
190
        except NoResultFound:
191
            raise HTTPNotFound()
192
        except Exception as exc:
193
            logging.getLogger(__name__).log(logging.ERROR, exc)
194
            raise HTTPNotFound()
195
        else:
196
            return dict(
197
                job=job,
198
                sources=SOURCES
199
            )
200
201