Skip to content

Commit

Permalink
Merge pull request #49 from stephengtuggy/development
Browse files Browse the repository at this point in the history
Merge development into master in preparation for a release
  • Loading branch information
stephengtuggy authored Aug 13, 2020
2 parents 09de229 + 6cbc66e commit 056ca92
Show file tree
Hide file tree
Showing 20 changed files with 364 additions and 55 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
steps:
- checkout
- run: |
curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` -o ~/docker-compose
curl -L https://github.com/docker/compose/releases/download/1.26.2/docker-compose-`uname -s`-`uname -m` -o ~/docker-compose
chmod +x ~/docker-compose
sudo mv ~/docker-compose /usr/local/bin/docker-compose
- run: |
Expand Down
38 changes: 38 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'bug'
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser: [e.g. chrome, safari]
- Version: [e.g. 22]

**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser: [e.g. stock browser, safari]
- Version: [e.g. 22]

**Additional context**
Add any other context about the problem here.
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'enhancement'
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
9 changes: 9 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Pull Request

Thank you for contributing to `job-history`.

**What does your Pull Request seek to accomplish?**

**Please list any related issues, using [closing keywords](https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) if appropriate**

Thanks again!
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# job-history

[![stephengtuggy](https://circleci.com/gh/stephengtuggy/job-history.svg?style=shield)](https://circleci.com/gh/stephengtuggy/job-history)

## Overview

This is a web app that lets you enter info about your current and past jobs into a database. You can then view this info later on, when you need to fill out a job application. This way, you won't have to remember everything every time. And you can refine the wording on, for example, your "Contributions and Accomplishments" section over time.
Expand All @@ -8,7 +10,7 @@ This is a web app that lets you enter info about your current and past jobs into

This app runs in `Docker`. You will need both Docker and Docker Compose to build and run it. On macOS and Windows, the easiest way to get these products is to download and install Docker Desktop Community Edition.

Also, you will need a copy of a file called `.env`. Ask me for this file, and I can send you one, via a more secure channel than GitHub. Place this file in the `app` folder just off the root of your local working copy of this repo.
Also, you will need a copy of a file called `.env`. Ask me for this file, and I can send you one, via a more secure channel than GitHub. Place this file in the root folder of your local working copy of this repo.

Once you have these items in place, run the command `docker-compose up --build`, either in PowerShell on Windows, or in Terminal on macOS or Linux. You should see Docker Compose pulling the latest copy of each source docker image, then building the main image for this app, and finally, spinning up both containers.

Expand All @@ -24,7 +26,7 @@ After the createsuperuser command, follow the prompts to set up your first user

## Use

Now comes the fun part. Under `JOB HISTORY`, click on `EMPLOYERS`, and enter your employers, one at a time. (Employers that you have worked for in the past ten years is probably sufficient.)
Now, down to business. Under `JOB HISTORY`, click on `EMPLOYERS`, and enter your employers, one at a time. (Employers that you have worked for in the past ten years is probably sufficient.)

Finally, click on the `JOB HISTORY` breadcrumb; click on `POSITIONS`; and start entering the positions you have held at each employer, along with the time periods for each.

Expand Down
10 changes: 8 additions & 2 deletions app/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
FROM python:3.7-buster

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

WORKDIR /usr/src/app

RUN apt-get -y update
RUN apt-get -y upgrade
# Netcat is used by tcp-port-wait.sh
RUN apt-get -y install netcat postgresql-client libgdal-dev
RUN apt-get -y dist-upgrade

RUN python -m pip install --upgrade --upgrade-strategy eager pip

RUN mkdir -p /usr/src/app
COPY ./requirements.txt /usr/src/app
RUN pip install -r ./requirements.txt
RUN python -m pip install --upgrade --upgrade-strategy eager --use-feature=2020-resolver -r ./requirements.txt

COPY . /usr/src/app

Expand Down
1 change: 1 addition & 0 deletions app/jobHistory/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class JobTimePeriodInline(admin.TabularInline):


class PositionAdmin(admin.ModelAdmin):
model = Position
inlines = [JobTimePeriodInline]


Expand Down
33 changes: 33 additions & 0 deletions app/jobHistory/migrations/0005_auto_20200808_2225.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 2.2.15 on 2020-08-08 22:25

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('jobHistory', '0004_auto_20190804_1411'),
]

operations = [
migrations.AddConstraint(
model_name='jobtimeperiod',
constraint=models.CheckConstraint(check=models.Q(('is_current_position__exact', True), ('end_year__isnull', False), _connector='OR'), name='require_end_date_if_not_current_position'),
),
migrations.AddConstraint(
model_name='jobtimeperiod',
constraint=models.CheckConstraint(check=models.Q(('is_current_position__exact', False), models.Q(('end_year__isnull', True), ('end_month__isnull', True), ('end_day__isnull', True)), _connector='OR'), name='leave_end_date_blank_if_current_position'),
),
migrations.AddConstraint(
model_name='jobtimeperiod',
constraint=models.CheckConstraint(check=models.Q(('start_month__isnull', False), ('start_day__isnull', True), _connector='OR'), name='require_start_month_if_start_day_specified'),
),
migrations.AddConstraint(
model_name='jobtimeperiod',
constraint=models.CheckConstraint(check=models.Q(('end_year__isnull', False), models.Q(('end_month__isnull', True), ('end_day__isnull', True)), _connector='OR'), name='require_end_year_if_end_month_specified'),
),
migrations.AddConstraint(
model_name='jobtimeperiod',
constraint=models.CheckConstraint(check=models.Q(('end_month__isnull', False), ('end_day__isnull', True), _connector='OR'), name='require_end_month_if_end_day_specified'),
),
]
43 changes: 43 additions & 0 deletions app/jobHistory/migrations/0006_auto_20200808_2342.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Generated by Django 2.2.15 on 2020-08-08 23:42

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('jobHistory', '0005_auto_20200808_2225'),
]

operations = [
migrations.AlterField(
model_name='jobtimeperiod',
name='end_day',
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='End Day'),
),
migrations.AlterField(
model_name='jobtimeperiod',
name='end_month',
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='End Month'),
),
migrations.AlterField(
model_name='jobtimeperiod',
name='end_year',
field=models.PositiveIntegerField(blank=True, null=True, verbose_name='End Year'),
),
migrations.AlterField(
model_name='jobtimeperiod',
name='hours_per_week',
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='Hours per Week'),
),
migrations.AlterField(
model_name='jobtimeperiod',
name='start_day',
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='Start Day'),
),
migrations.AlterField(
model_name='jobtimeperiod',
name='start_month',
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='Start Month'),
),
]
34 changes: 34 additions & 0 deletions app/jobHistory/migrations/0007_auto_20200813_1931.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Django 2.2.15 on 2020-08-13 19:31

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('jobHistory', '0006_auto_20200808_2342'),
]

operations = [
migrations.AlterField(
model_name='jobtimeperiod',
name='end_day',
field=models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(31)], verbose_name='End Day'),
),
migrations.AlterField(
model_name='jobtimeperiod',
name='end_month',
field=models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(12)], verbose_name='End Month'),
),
migrations.AlterField(
model_name='jobtimeperiod',
name='start_day',
field=models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(31)], verbose_name='Start Day'),
),
migrations.AlterField(
model_name='jobtimeperiod',
name='start_month',
field=models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(12)], verbose_name='Start Month'),
),
]
53 changes: 40 additions & 13 deletions app/jobHistory/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import datetime

from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from django.utils.translation import gettext_lazy as _

Expand Down Expand Up @@ -49,7 +51,7 @@ class Meta:
supervisor_state_or_province = models.CharField(max_length=200, blank=True, null=False, verbose_name=_('Supervisor State or Province'))
supervisor_zip_or_postal_code = models.CharField(max_length=50, blank=True, null=False, verbose_name=_('Supervisor Zip Code or Postal Code'))
supervisor_country = models.CharField(max_length=200, blank=True, null=False, verbose_name=_('Supervisor Country'))
can_contact = models.BooleanField(null=False, verbose_name=_('Can Contact?'))
can_contact = models.BooleanField(blank=False, null=False, verbose_name=_('Can Contact?'))

def __str__(self):
return self.title + " @ " + str(self.employer)
Expand All @@ -58,18 +60,25 @@ def __str__(self):
class JobTimePeriod(models.Model):
class Meta:
verbose_name = _('Job Time Period')
constraints = [
models.CheckConstraint(check=(models.Q(is_current_position__exact=True) | models.Q(end_year__isnull=False)), name='require_end_date_if_not_current_position'),
models.CheckConstraint(check=(models.Q(is_current_position__exact=False) | (models.Q(end_year__isnull=True) & models.Q(end_month__isnull=True) & models.Q(end_day__isnull=True))), name='leave_end_date_blank_if_current_position'),
models.CheckConstraint(check=(models.Q(start_month__isnull=False) | models.Q(start_day__isnull=True)), name='require_start_month_if_start_day_specified'),
models.CheckConstraint(check=(models.Q(end_year__isnull=False) | (models.Q(end_month__isnull=True) & models.Q(end_day__isnull=True))), name='require_end_year_if_end_month_specified'),
models.CheckConstraint(check=(models.Q(end_month__isnull=False) | models.Q(end_day__isnull=True)), name='require_end_month_if_end_day_specified')
]

position = models.ForeignKey(Position, on_delete=models.CASCADE, verbose_name=_('Position'))
start_year = models.PositiveIntegerField(null=False, verbose_name=_('Start Year'))
start_month = models.PositiveSmallIntegerField(null=True, verbose_name=_('Start Month'))
start_day = models.PositiveSmallIntegerField(null=True, verbose_name=_('Start Day'))
is_current_position = models.BooleanField(null=False, default=True, verbose_name=_('Current Position?'))
end_year = models.PositiveIntegerField(null=True, verbose_name=_('End Year'))
end_month = models.PositiveSmallIntegerField(null=True, verbose_name=_('End Month'))
end_day = models.PositiveSmallIntegerField(null=True, verbose_name=_('End Day'))
start_year = models.PositiveIntegerField(blank=False, null=False, verbose_name=_('Start Year'))
start_month = models.PositiveSmallIntegerField(blank=True, null=True, validators=[MinValueValidator(1), MaxValueValidator(12)], verbose_name=_('Start Month'))
start_day = models.PositiveSmallIntegerField(blank=True, null=True, validators=[MinValueValidator(1), MaxValueValidator(31)], verbose_name=_('Start Day'))
is_current_position = models.BooleanField(blank=False, null=False, default=True, verbose_name=_('Current Position?'))
end_year = models.PositiveIntegerField(blank=True, null=True, verbose_name=_('End Year'))
end_month = models.PositiveSmallIntegerField(blank=True, null=True, validators=[MinValueValidator(1), MaxValueValidator(12)], verbose_name=_('End Month'))
end_day = models.PositiveSmallIntegerField(blank=True, null=True, validators=[MinValueValidator(1), MaxValueValidator(31)], verbose_name=_('End Day'))
starting_pay = models.CharField(max_length=50, blank=False, null=False, verbose_name=_('Starting Pay'))
ending_pay = models.CharField(max_length=50, blank=False, null=False, verbose_name=_('Ending Pay'))
hours_per_week = models.PositiveSmallIntegerField(null=True, verbose_name=_('Hours per Week'))
hours_per_week = models.PositiveSmallIntegerField(blank=True, null=True, verbose_name=_('Hours per Week'))
contributions_and_accomplishments = models.TextField(blank=True, null=False, verbose_name=_('Contributions and Accomplishments'))
work_city = models.CharField(max_length=200, blank=True, null=False, verbose_name=_('Work City'))
work_county_or_parish = models.CharField(max_length=200, blank=True, null=False, verbose_name=_('Work County or Parish'))
Expand All @@ -79,22 +88,40 @@ class Meta:

@property
def startDate(self):
return datetime.date(self.start_year, self.start_month, self.start_day)
return datetime.date(self.start_year, self.start_month or 1, self.start_day or 1)

@property
def endDate(self):
if self.is_current_position:
return datetime.date.today()
else:
return datetime.date(self.end_year, self.end_month, self.end_day)
return datetime.date(self.end_year or datetime.MINYEAR, self.end_month or 1, self.end_day or 1)

def __str__(self):
ret_val = str(self.position)
ret_val += " from "
ret_val += str(self.startDate)
try:
ret_val += str(self.startDate)
except ValueError as e:
ret_val += '<Invalid start date value>'
ret_val += " to "
if self.is_current_position:
ret_val += "present"
else:
ret_val += str(self.endDate)
try:
ret_val += str(self.endDate)
except ValueError as e:
ret_val += '<Invalid end date value>'
return ret_val

def clean(self):
if self.is_current_position and self.end_year is not None:
raise ValidationError(_('Leave end date blank if this is your current position'))
elif self.end_year is None and not self.is_current_position:
raise ValidationError(_('End date (at least end year) is required if this is not your current position'))
elif self.start_month is None and self.start_day is not None:
raise ValidationError(_('Start month is required if start day is specified'))
elif self.end_year is None and (self.end_month is not None or self.end_day is not None):
raise ValidationError(_('End year is required if end month or end day is specified'))
elif self.end_month is None and self.end_day is not None:
raise ValidationError(_('End month is required if end day is specified'))
7 changes: 7 additions & 0 deletions app/jobHistory/static/css/jobHistory.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
body {
background-color: rgb(240, 248, 255);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
3 changes: 2 additions & 1 deletion app/jobHistory/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from django.urls import path
from .views import IndexView
from .views import IndexView, JobTimePeriodDetailView

app_name = 'jobHistory'

urlpatterns = [
path('', IndexView.as_view(), name='index'),
path('<int:pk>/', JobTimePeriodDetailView.as_view(), name='job-time-period-detail'),
]
13 changes: 10 additions & 3 deletions app/jobHistory/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@

from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render
from django.views import generic
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView #, SingleObjectTemplateResponseMixin

from .models import JobTimePeriod

# Create your views here.
class IndexView(LoginRequiredMixin, generic.ListView):

class IndexView(LoginRequiredMixin, ListView):
template_name = 'jobHistory/index.html'
context_object_name = 'chronological_job_list'

def get_queryset(self):
job_time_periods = JobTimePeriod.objects.all()
return sorted(job_time_periods, key=operator.attrgetter('endDate'), reverse=True)


class JobTimePeriodDetailView(LoginRequiredMixin, DetailView):
model = JobTimePeriod


Loading

0 comments on commit 056ca92

Please sign in to comment.