-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #959 from openedx/iahmad/ENT-9470
feat: Added models and commands for enterprise-jobs association
- Loading branch information
Showing
16 changed files
with
539 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
""" | ||
Job app - implementation for enterprise-job relationship. | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
""" | ||
Admin for jobs models. | ||
""" | ||
from django.contrib import admin | ||
from simple_history.admin import SimpleHistoryAdmin | ||
|
||
from enterprise_catalog.apps.jobs.models import Job, JobEnterprise, JobSkill | ||
|
||
|
||
@admin.register(Job) | ||
class JobAdmin(admin.ModelAdmin): | ||
""" | ||
Django admin for Jobs. | ||
""" | ||
list_display = ('job_id', 'external_id', 'title', 'description', ) | ||
search_fields = ('job_id', 'title', 'description', ) | ||
|
||
|
||
@admin.register(JobEnterprise) | ||
class JobEnterpriseAdmin(SimpleHistoryAdmin): | ||
""" | ||
Django admin for Enterprise Jobs. | ||
""" | ||
list_display = ('enterprise_uuid', 'created', 'modified', ) | ||
search_fields = ('enterprise_uuid', ) | ||
|
||
|
||
@admin.register(JobSkill) | ||
class JobSkillAdmin(SimpleHistoryAdmin): | ||
""" | ||
Django admin for Job Skills. | ||
""" | ||
list_display = ('skill_id', 'name', 'significance', 'created', 'modified',) | ||
search_fields = ('name', ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
""" | ||
Job app - implementation for enterprise-job relationship. | ||
""" | ||
from django.apps import AppConfig | ||
|
||
|
||
class JobConfig(AppConfig): | ||
name = 'jobs' | ||
default = False |
Empty file.
Empty file.
65 changes: 65 additions & 0 deletions
65
enterprise_catalog/apps/jobs/management/commands/fetch_jobs_skills.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
""" | ||
Management command for fetching jobs skills from taxonomy connector | ||
""" | ||
import logging | ||
|
||
from django.core.management.base import BaseCommand | ||
|
||
from enterprise_catalog.apps.api_client.discovery import DiscoveryApiClient | ||
from enterprise_catalog.apps.jobs.models import Job, JobSkill | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class Command(BaseCommand): | ||
""" | ||
Management command for fetching job skills from taxonomy connector | ||
Example Usage: | ||
>> python manage.py fetch_jobs_skills | ||
""" | ||
help = ( | ||
'Fetch the skills associated with jobs from taxonomy connector' | ||
) | ||
|
||
def _process_job_skills(self, results): | ||
""" | ||
Process the job skills fetched from taxonomy connector. | ||
""" | ||
for result in results: | ||
try: | ||
job, _ = Job.objects.update_or_create( | ||
job_id=result.get('id'), | ||
title=result.get('name'), | ||
description=result.get('description'), | ||
external_id=result.get('external_id') | ||
) | ||
job_skills = result.get('skills') | ||
for item in job_skills: | ||
skill = item.get('skill') | ||
JobSkill.objects.update_or_create( | ||
job=job, | ||
skill_id=skill.get('id'), | ||
name=skill.get('name'), | ||
significance=item.get('significance') | ||
) | ||
except Exception as exc: # pylint: disable=broad-exception-caught | ||
job_id = result.get('id') | ||
logger.exception(f'Could not store job skills. job id {job_id} {exc}') | ||
|
||
def handle(self, *args, **options): | ||
""" | ||
Fetch the skills associated with jobs from taxonomy connector. | ||
""" | ||
page = 1 | ||
try: | ||
results, has_next = DiscoveryApiClient().get_jobs_skills(page=page) | ||
self._process_job_skills(results) | ||
|
||
while has_next: | ||
page += 1 | ||
results, has_next = DiscoveryApiClient().get_jobs_skills(page=page) | ||
self._process_job_skills(results) | ||
except Exception as exc: # pylint: disable=broad-exception-caught | ||
logger.exception(f'Could not retrieve job skills for page {page} {exc}') |
71 changes: 71 additions & 0 deletions
71
enterprise_catalog/apps/jobs/management/commands/process_enterprise_jobs.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
""" | ||
Management command for associating jobs with enterprises | ||
""" | ||
import logging | ||
|
||
from django.core.management.base import BaseCommand | ||
|
||
from enterprise_catalog.apps.catalog.algolia_utils import ( | ||
get_initialized_algolia_client, | ||
) | ||
from enterprise_catalog.apps.catalog.models import EnterpriseCatalog | ||
from enterprise_catalog.apps.jobs.models import Job, JobEnterprise, JobSkill | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class Command(BaseCommand): | ||
""" | ||
Management command for associating jobs with enterprises via common skills | ||
Example Usage: | ||
>> python manage.py process_enterprise_jobs | ||
""" | ||
help = ( | ||
'Associate jobs with enterprises via common skills' | ||
) | ||
|
||
def handle(self, *args, **options): | ||
""" | ||
Associate jobs with enterprises via common skills | ||
""" | ||
logger.info("Generating enterprise job association...") | ||
algolia_client = get_initialized_algolia_client() | ||
enterprise_uuids = set() | ||
enterprise_catalogs = EnterpriseCatalog.objects.all() | ||
for enterprise_catalog in enterprise_catalogs: | ||
enterprise_uuids.add(enterprise_catalog.enterprise_uuid) | ||
|
||
jobs = Job.objects.all() | ||
associated_jobs = set() | ||
for enterprise_uuid in enterprise_uuids: | ||
for job in jobs: | ||
try: | ||
job_skills = JobSkill.objects.filter(job=job).order_by('-significance')[:3] # Get top 3 skills | ||
search_query = { | ||
'filters': f'(skill_names:{job_skills[0].name} OR \ | ||
skill_names:{job_skills[1].name} OR \ | ||
skill_names:{job_skills[2]}.name) AND \ | ||
enterprise_customer_uuids:{enterprise_uuid}', | ||
'maxFacetHits': 50 | ||
} | ||
response = algolia_client.algolia_index.search_for_facet_values('skill_names', '', search_query) | ||
for hit in response.get('facetHits', []): | ||
if hit.get('count') > 1: | ||
JobEnterprise.objects.update_or_create( | ||
job=job, | ||
enterprise_uuid=enterprise_uuid | ||
) | ||
associated_jobs.add(job.job_id) | ||
break | ||
except Exception: # pylint: disable=broad-exception-caught | ||
logger.error( | ||
'[PROCESS_ENTERPRISE_JOBS] Failure in processing \ | ||
enterprise "%s" and job: "%s".', | ||
enterprise_uuid, | ||
job.job_id, | ||
exc_info=True | ||
) | ||
else: | ||
JobEnterprise.objects.all().exclude(job_id__in=associated_jobs).delete() |
Oops, something went wrong.