diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..92860cf0d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,26 @@ +# Hasgeek code style config +root = True + +# For all files +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +max_line_length = 88 +tab_width = 8 +trim_trailing_whitespace = true + +# Python code +[*.py] +indent_size = 4 + +# Makefile +[Makefile] +indent_style = tab +indent_size = tab + +# Markdown +[*.{md,md.jinja2}] +trim_trailing_whitespace = false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c72c29e87..3db510de2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,13 +13,7 @@ repos: hooks: - id: ruff args: ['--fix', '--exit-non-zero-on-fix'] - # Extra args, only after removing flake8 and yesqa: '--extend-select', 'RUF100' - - repo: https://github.com/asottile/pyupgrade - rev: v3.15.2 - hooks: - - id: pyupgrade - args: - ['--keep-runtime-typing', '--py3-plus', '--py36-plus', '--py37-plus'] + - id: ruff-format - repo: https://github.com/asottile/yesqa rev: v1.5.0 hooks: @@ -43,10 +37,6 @@ repos: - id: isort additional_dependencies: - toml - - repo: https://github.com/psf/black - rev: 24.4.2 - hooks: - - id: black - repo: https://github.com/PyCQA/flake8 rev: 7.0.0 hooks: @@ -66,11 +56,10 @@ repos: args: ['-c', 'pyproject.toml'] additional_dependencies: - bandit[toml] - - repo: https://github.com/pre-commit/mirrors-prettier - rev: v4.0.0-alpha.8 + - repo: https://github.com/pycontribs/mirrors-prettier + rev: v3.3.1 hooks: - id: prettier - args: ['--single-quote', '--trailing-comma', 'es5'] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 hooks: diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..de056073a --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +**/*.md diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index a425d3f76..000000000 --- a/.prettierrc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - singleQuote: true, - trailingComma: 'es5', -}; diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..544138be4 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/hasjob/assets/js/app.js b/hasjob/assets/js/app.js index 53bc58220..060c7d153 100644 --- a/hasjob/assets/js/app.js +++ b/hasjob/assets/js/app.js @@ -67,10 +67,7 @@ window.Hasjob.JobPost = { var outerTemplate = document.createElement('li'); var innerTemplate = document.createElement('a'); var node, outer, inner; - outerTemplate.setAttribute( - 'class', - 'col-xs-12 col-md-3 col-sm-4 animated shake' - ); + outerTemplate.setAttribute('class', 'col-xs-12 col-md-3 col-sm-4 animated shake'); innerTemplate.setAttribute('class', 'stickie'); innerTemplate.setAttribute('rel', 'bookmark'); // replaces the group with individual stickies when clicked @@ -119,9 +116,7 @@ window.Hasjob.StickieList = { $('ul#stickie-area').append(data.trim()); stickielist.loadmoreRactive.set('loading', false); stickielist.loadmoreRactive.set('error', false); - window.dispatchEvent( - Hasjob.Util.createCustomEvent('onStickiesPagination') - ); + window.dispatchEvent(Hasjob.Util.createCustomEvent('onStickiesPagination')); }, error: function () { stickielist.loadmoreRactive.set('error', true); @@ -170,8 +165,7 @@ window.Hasjob.StickieList = { var filterParams = window.Hasjob.Filters.toParam(); var searchUrl = window.Hasjob.Config.baseURL; if (filterParams.length) { - searchUrl = - window.Hasjob.Config.baseURL + '?' + window.Hasjob.Filters.toParam(); + searchUrl = window.Hasjob.Config.baseURL + '?' + window.Hasjob.Filters.toParam(); } $.ajax(searchUrl, { method: 'POST', @@ -182,9 +176,7 @@ window.Hasjob.StickieList = { $('#main-content').html(data); window.Hasjob.Filters.refresh(); NProgress.done(); - window.dispatchEvent( - Hasjob.Util.createCustomEvent('onStickiesRefresh') - ); + window.dispatchEvent(Hasjob.Util.createCustomEvent('onStickiesRefresh')); }, }); history.replaceState({ reloadOnPop: true }, '', window.location.href); @@ -237,7 +229,7 @@ window.Hasjob.StickieList = { value, 1, 1, - 1 + 1, ).data; var colourHex; if (rgba[0] > 255 || rgba[1] > 255 || rgba[2] > 255) { @@ -265,7 +257,7 @@ window.Hasjob.StickieList = { Hasjob.StickieList.setGradientColour( $(this).data('funnel-name'), $(this).data('funnel-value'), - $(this).attr('id') + $(this).attr('id'), ); } }); @@ -273,19 +265,19 @@ window.Hasjob.StickieList = { createGradientColour: function () { Hasjob.StickieList.createGradientColourScale( 'impressions', - Hasjob.Config.MaxCounts.max_impressions + Hasjob.Config.MaxCounts.max_impressions, ); Hasjob.StickieList.createGradientColourScale( 'views', - Hasjob.Config.MaxCounts.max_views + Hasjob.Config.MaxCounts.max_views, ); Hasjob.StickieList.createGradientColourScale( 'opens', - Hasjob.Config.MaxCounts.max_opens + Hasjob.Config.MaxCounts.max_opens, ); Hasjob.StickieList.createGradientColourScale( 'applied', - Hasjob.Config.MaxCounts.max_applied + Hasjob.Config.MaxCounts.max_applied, ); }, initFunnelViz: function () { @@ -299,7 +291,7 @@ window.Hasjob.StickieList = { Hasjob.StickieList.renderGradientColour(); } }, - false + false, ); window.addEventListener( @@ -309,7 +301,7 @@ window.Hasjob.StickieList = { Hasjob.StickieList.renderGradientColour(); } }, - false + false, ); window.addEventListener( @@ -319,7 +311,7 @@ window.Hasjob.StickieList = { Hasjob.StickieList.renderGradientColour(); } }, - false + false, ); }, }; @@ -327,7 +319,7 @@ window.Hasjob.StickieList = { window.Hasjob.Filters = { toParam: function () { var sortedFilterParams = this.formatFilterParams( - $('#js-job-filters').serializeArray() + $('#js-job-filters').serializeArray(), ); if (sortedFilterParams.length) { return $.param(sortedFilterParams); @@ -452,10 +444,7 @@ window.Hasjob.Filters = { if ($(this).val() !== lastKeyword) { window.clearTimeout(keywordTimeout); lastKeyword = $(this).val(); - keywordTimeout = window.setTimeout( - window.Hasjob.StickieList.refresh, - 1000 - ); + keywordTimeout = window.setTimeout(window.Hasjob.StickieList.refresh, 1000); } }); @@ -560,7 +549,7 @@ window.Hasjob.Filters = { formParams[fpIndex].value = ''; } else { formParams[fpIndex].value = Hasjob.PaySlider.toNumeric( - formParams[fpIndex].value + formParams[fpIndex].value, ); if (formParams[fpIndex].value === '0') { formParams[fpIndex].value = ''; @@ -616,10 +605,7 @@ window.Hasjob.Currency.indian_rupee_encoder = function (value) { var otherNumbers = value.substring(0, value.length - 3); if (otherNumbers !== '') lastThree = ',' + lastThree; var res = - '₹' + - otherNumbers.replace(/\B(?=(\d{2})+(?!\d))/g, ',') + - lastThree + - afterPoint; + '₹' + otherNumbers.replace(/\B(?=(\d{2})+(?!\d))/g, ',') + lastThree + afterPoint; return res; }; @@ -747,7 +733,7 @@ window.Hasjob.PaySlider.prototype.resetSlider = function (currency) { range: Hasjob.PaySlider.range(currency), format: Hasjob.Currency.wNumbFormat(currency), }, - true + true, ); this.slider.Link('lower').to($(this.minField)); @@ -808,16 +794,12 @@ $(function () { // set initial value for the currency radio button var presetCurrency = - (window.Hasjob.Config && window.Hasjob.Config.selectedFilters.currency) || - 'NA'; - $.each( - $("input[type='radio'][name='currency']"), - function (index, currencyRadio) { - if ($(currencyRadio).val() === presetCurrency) { - $(currencyRadio).attr('checked', 'checked'); - } + (window.Hasjob.Config && window.Hasjob.Config.selectedFilters.currency) || 'NA'; + $.each($("input[type='radio'][name='currency']"), function (index, currencyRadio) { + if ($(currencyRadio).val() === presetCurrency) { + $(currencyRadio).attr('checked', 'checked'); } - ); + }); // preset equity if (window.Hasjob.Config && window.Hasjob.Config.selectedFilters.equity) { @@ -844,8 +826,7 @@ $(function () { }; var paySlider = new Hasjob.PaySlider({ - start: - (window.Hasjob.Config && window.Hasjob.Config.selectedFilters.pay) || 0, + start: (window.Hasjob.Config && window.Hasjob.Config.selectedFilters.pay) || 0, selector: '#pay-slider', minField: '#job-filters-payval', }); diff --git a/hasjob/assets/service-worker-template.js b/hasjob/assets/service-worker-template.js index 29326f79c..e3fdd2db5 100644 --- a/hasjob/assets/service-worker-template.js +++ b/hasjob/assets/service-worker-template.js @@ -1,5 +1,5 @@ importScripts( - 'https://unpkg.com/workbox-sw@2.1.2/build/importScripts/workbox-sw.prod.v2.1.2.js' + 'https://unpkg.com/workbox-sw@2.1.2/build/importScripts/workbox-sw.prod.v2.1.2.js', ); const workboxSW = new self.WorkboxSW({ @@ -15,7 +15,7 @@ workboxSW.router.registerRoute( workboxSW.strategies.networkFirst({ cacheName: 'assets', }), - 'GET' + 'GET', ); //For development setup caching of assets @@ -24,7 +24,7 @@ workboxSW.router.registerRoute( workboxSW.strategies.networkFirst({ cacheName: 'baseframe-local', }), - 'GET' + 'GET', ); workboxSW.router.registerRoute( @@ -32,7 +32,7 @@ workboxSW.router.registerRoute( workboxSW.strategies.networkFirst({ cacheName: 'cdn-libraries', }), - 'GET' + 'GET', ); workboxSW.router.registerRoute( @@ -40,7 +40,7 @@ workboxSW.router.registerRoute( workboxSW.strategies.networkFirst({ cacheName: 'cdn-libraries', }), - 'GET' + 'GET', ); workboxSW.router.registerRoute( @@ -48,7 +48,7 @@ workboxSW.router.registerRoute( workboxSW.strategies.networkFirst({ cacheName: 'images', }), - 'GET' + 'GET', ); workboxSW.router.registerRoute( @@ -56,7 +56,7 @@ workboxSW.router.registerRoute( workboxSW.strategies.networkFirst({ cacheName: 'images', }), - 'GET' + 'GET', ); workboxSW.router.registerRoute( @@ -64,7 +64,7 @@ workboxSW.router.registerRoute( workboxSW.strategies.networkFirst({ cacheName: 'images', }), - 'GET' + 'GET', ); workboxSW.router.registerRoute( @@ -72,7 +72,7 @@ workboxSW.router.registerRoute( workboxSW.strategies.networkFirst({ cacheName: 'fonts', }), - 'GET' + 'GET', ); workboxSW.router.registerRoute( @@ -80,7 +80,7 @@ workboxSW.router.registerRoute( workboxSW.strategies.networkFirst({ cacheName: 'fonts', }), - 'GET' + 'GET', ); /* The service worker handles all fetch requests. If fetching of job post page or @@ -122,7 +122,7 @@ self.addEventListener('install', (event) => { return caches.open('hasjob-offline').then(function (cache) { return cache.put('offline', response); }); - } - ) + }, + ), ); }); diff --git a/hasjob/assets/webpack.config.js b/hasjob/assets/webpack.config.js index 9f9c9428c..8ae099938 100644 --- a/hasjob/assets/webpack.config.js +++ b/hasjob/assets/webpack.config.js @@ -32,7 +32,7 @@ ManifestPlugin.prototype.apply = function (compiler) { }); require('fs').writeFileSync( path.join(__dirname, this.manifestPath), - JSON.stringify(parsed_stats) + JSON.stringify(parsed_stats), ); }); }; @@ -98,8 +98,7 @@ module.exports = { return ( module.resource && /\.js$/.test(module.resource) && - module.resource.indexOf(path.join(__dirname, '/node_modules')) === - 0 + module.resource.indexOf(path.join(__dirname, '/node_modules')) === 0 ); }, }), diff --git a/hasjob/static/embed.js b/hasjob/static/embed.js index 0615d710a..b10485e96 100644 --- a/hasjob/static/embed.js +++ b/hasjob/static/embed.js @@ -40,9 +40,7 @@ if (hostnames.indexOf(event.origin) !== -1) { var message = JSON.parse(event.data); if (message.context == 'iframe.resize' && message.id) { - document - .getElementById(message.id) - .setAttribute('height', message.height); + document.getElementById(message.id).setAttribute('height', message.height); } } } diff --git a/hasjob/tagging.py b/hasjob/tagging.py index ed1749167..2078b7c17 100644 --- a/hasjob/tagging.py +++ b/hasjob/tagging.py @@ -55,6 +55,7 @@ def extract_entity_names(tree: nltk.Tree) -> list[str]: return set(entity_names) +@rq.job('hasjob') def tag_locations(jobpost_id): with app.test_request_context(): post = JobPost.query.get(jobpost_id) diff --git a/hasjob/utils.py b/hasjob/utils.py index 8e063f664..62c3b69da 100644 --- a/hasjob/utils.py +++ b/hasjob/utils.py @@ -150,9 +150,9 @@ def redactemail(data, message='[redacted]'): """ Remove email addresses from the given text, replacing with a redacted message. - >>> redactemail(u"Send email to test@example.com and you are all set.") + >>> redactemail("Send email to test@example.com and you are all set.") u'Send email to [redacted] and you are all set.' - >>> redactemail(u"Send email to test@example.com and you are all set.", '[hidden]') + >>> redactemail("Send email to test@example.com and you are all set.", '[hidden]') u'Send email to [hidden] and you are all set.' """ return EMAIL_RE.sub(message, data) @@ -164,13 +164,21 @@ def scrubemail(data, rot13=False, css_junk=None): and optionally obfuscate them with ROT13 and empty CSS classes, to hide from spambots. - >>> scrubemail(u"Send email to test@example.com and you are all set.") + >>> scrubemail("Send email to test@example.com and you are all set.") u'Send email to test@example.com and you are all set.' - >>> scrubemail(u"Send email to test@example.com and you are all set.", rot13=True) + >>> scrubemail("Send email to test@example.com and you are all set.", rot13=True) u'Send email to test@example.com and you are all set.' - >>> scrubemail(u"Send email to test@example.com and you are all set.", rot13=True, css_junk='z') + >>> scrubemail( + ... "Send email to test@example.com and you are all set.", + ... rot13=True, + ... css_junk='z', + ... ) u'Send email to test@noexampspamle.com and you are all set.' - >>> scrubemail(u"Send email to test@example.com and you are all set.", rot13=False, css_junk=('z', 'y')) + >>> scrubemail( + ... "Send email to test@example.com and you are all set.", + ... rot13=False, + ... css_junk=('z', 'y'), + ... ) u'Send email to test@noexampspamle.com and you are all set.' """ @@ -227,7 +235,7 @@ def striptags(text): ' title ' >>> striptags('plain text') 'plain text' - >>> striptags(u'word
break') + >>> striptags('word
break') u'word break' """ return TAGSPLIT_RE.sub(' ', text) @@ -246,7 +254,7 @@ def getwords(text): ['one', 'two'] >>> getwords("does not is doesn't") ['does', 'not', 'is', 'doesn', 't'] - >>> getwords(u'hola unicode!') + >>> getwords('hola unicode!') [u'hola', u'unicode'] """ result = WORDSPLIT_RE.split(text) diff --git a/hasjob/views/admin.py b/hasjob/views/admin.py index 379f3d351..87bcce393 100644 --- a/hasjob/views/admin.py +++ b/hasjob/views/admin.py @@ -10,11 +10,11 @@ def tabs(cls): # noqa: N805 views = ((name, getattr(cls, name)) for name in cls.__views__) tabviews = sorted( (view.data.get('index', 0), name, view) - for name, view, in views + for name, view in views if view.data.get('tab') ) return ((name, view.data['title'], view) for index, name, view in tabviews) @property def current_tab(self): - return self.current_handler.name + return self.current_method.name diff --git a/hasjob/views/admin_filterset.py b/hasjob/views/admin_filterset.py index 458ecf0ab..62f2106bc 100644 --- a/hasjob/views/admin_filterset.py +++ b/hasjob/views/admin_filterset.py @@ -11,7 +11,6 @@ @route('/f') class AdminFiltersetView(UrlForView, ModelView[Filterset]): - route_model_map = {'name': 'name'} def loader(self, name=None): diff --git a/tests/test_job_post.js b/tests/test_job_post.js index ee4a2b18d..3b0304b9d 100644 --- a/tests/test_job_post.js +++ b/tests/test_job_post.js @@ -36,7 +36,7 @@ casper.test.begin('Hasjob Post A Job Flow', 13, function suite(test) { document.querySelector('#passwordlogin').submit(); }, test_username, - test_password + test_password, ); }); @@ -59,8 +59,7 @@ casper.test.begin('Hasjob Post A Job Flow', 13, function suite(test) { 'What is the answer to Life, the Universe and Everything?'; document.querySelector('#company_name').value = 'Acme Corp'; document.querySelector('#company_url').value = 'http://mailinator.com/'; - document.querySelector('#poster_email').value = - 'travishasjob@mailinator.com'; + document.querySelector('#poster_email').value = 'travishasjob@mailinator.com'; document.querySelector('#newjob').submit(); }); }); @@ -70,9 +69,7 @@ casper.test.begin('Hasjob Post A Job Flow', 13, function suite(test) { test.assertUrlMatch(/view/, 'Job posted, now to review'); test.assertSelectorHasText('div.page-header>h2', 'Review this post'); casper.evaluate(function () { - document - .querySelector('input[value="This looks good, confirm it"]') - .click(); + document.querySelector('input[value="This looks good, confirm it"]').click(); }); });