summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorluxagraf <sng@luxagraf.net>2019-01-13 11:51:02 -0600
committerluxagraf <sng@luxagraf.net>2019-01-13 11:51:02 -0600
commitc4da428fc9ec439389b7473ba5638d9f82085475 (patch)
tree2c135804e201b3008fe56db25d993881a49da686 /app
parent120021d565eefa0318c487f0ff5707c7b9893b43 (diff)
updated income and resume apps
Diffstat (limited to 'app')
-rw-r--r--app/income/models.py13
-rw-r--r--app/income/parser.py42
-rw-r--r--app/income/views.py14
-rw-r--r--app/resume/admin.py18
-rw-r--r--app/resume/migrations/0004_job_resume.py37
-rw-r--r--app/resume/migrations/0005_job_slug.py18
-rw-r--r--app/resume/migrations/0006_auto_20190112_1257.py22
-rw-r--r--app/resume/migrations/0007_auto_20190113_1128.py18
-rw-r--r--app/resume/migrations/0008_auto_20190113_1139.py24
-rw-r--r--app/resume/migrations/0009_job_body_html.py18
-rw-r--r--app/resume/migrations/0010_auto_20190113_1147.py25
-rw-r--r--app/resume/models.py37
-rw-r--r--app/resume/urls.py29
-rw-r--r--app/resume/views.py10
-rw-r--r--app/utils/util.py11
15 files changed, 292 insertions, 44 deletions
diff --git a/app/income/models.py b/app/income/models.py
index 688d1d7..e5a351b 100644
--- a/app/income/models.py
+++ b/app/income/models.py
@@ -69,6 +69,9 @@ class InvoiceItem(models.Model):
time_end = models.DateTimeField(null=True, blank=True)
work_done = models.TextField(null=True, blank=True)
+ class Meta:
+ ordering = ('time_start',)
+
def __str__(self):
return str(self.time_start)
@@ -89,6 +92,12 @@ class InvoiceItem(models.Model):
half_period_seconds = period_seconds / 2
remainder = td.total_seconds() % period_seconds
if remainder >= half_period_seconds:
- return timedelta(seconds=td.total_seconds() + (period_seconds - remainder))
+ tdr = timedelta(seconds=td.total_seconds() + (period_seconds - remainder))
+ hours, remainder = divmod(tdr.total_seconds(), 3600)
+ r = remainder/3600
+ return float(hours)+r
else:
- return timedelta(seconds=td.total_seconds() - remainder)
+ tdr = timedelta(seconds=td.total_seconds() - remainder)
+ hours, remainder = divmod(tdr.total_seconds(), 3600)
+ r = remainder/3600
+ return float(hours)+r
diff --git a/app/income/parser.py b/app/income/parser.py
index 9524902..b19d039 100644
--- a/app/income/parser.py
+++ b/app/income/parser.py
@@ -1,19 +1,23 @@
-with open('timesheet.csv', newline='') as csvfile:
- reader = csv.reader(csvfile, delimiter=';')
- counter = 0
- f = "%Y-%m-%d %H:%M:%S"
- for row in reader:
- if counter > 0:
- timer = row[0]+' '+row[1]
- timerer = row[0]+' '+row[2]
- time_start = datetime.datetime.strptime(timer, f)
- time_end = datetime.datetime.strptime(timerer, f)
- print(row[4])
- print(timerer, time_end)
- InvoiceItem.objects.get_or_create(
- time_start=time_start,
- time_end=time_end,
- work_done=row[4]
- )
- counter = counter +1
-f = "%Y-%m-%d %H:%M:%S"
+import csv
+import datetime
+from .models import InvoiceItem
+
+
+def read_timesheet():
+ with open('timesheet.csv', newline='') as csvfile:
+ reader = csv.reader(csvfile, delimiter=';')
+ counter = 0
+ f = "%Y-%m-%d %H:%M:%S"
+ for row in reader:
+ if counter > 0:
+ print(row[4])
+ timer = row[0]+' '+row[1]
+ timerer = row[0]+' '+row[2]
+ time_start = datetime.datetime.strptime(timer, f)
+ time_end = datetime.datetime.strptime(timerer, f)
+ InvoiceItem.objects.get_or_create(
+ time_start=time_start,
+ time_end=time_end,
+ work_done=row[4]
+ )
+ counter = counter + 1
diff --git a/app/income/views.py b/app/income/views.py
index 2c3e34a..fc22c0d 100644
--- a/app/income/views.py
+++ b/app/income/views.py
@@ -20,8 +20,7 @@ class MonthlyInvoiceView(DetailView):
total_time = []
for item in context['object_list']:
total_time.append(item.rounded_total)
- duration = (sum(total_time, datetime.timedelta()))
- hours = duration.total_seconds() // 3600
+ hours = (sum(total_time))
context['total_hours'] = hours
context['total_billed'] = int(hours * 100)
context['invoice_number'] = self.object.id+21
@@ -37,10 +36,17 @@ class DownloadMonthlyInvoiceView(MonthlyInvoiceView):
logger = logging.getLogger('weasyprint')
logger.addHandler(logging.FileHandler('weasyprint.log'))
self.object = self.get_object() # assign the object to the view
- c = {'object': self.object}
+ context = self.get_context_data()
+ c = {
+ 'object': self.object,
+ 'object_list': context['object_list'],
+ 'total_hours': context['total_hours'],
+ 'total_billed': context['total_billed'],
+ 'invoice_number': self.object.id+23
+ }
t = render_to_string('details/invoice.html', c).encode('utf-8')
html = HTML(string=t, base_url=self.request.build_absolute_uri())
- pdf = html.write_pdf(stylesheets=[CSS(settings.MEDIA_ROOT + 'site/media/pdf_gen.css')], presentational_hints=True)
+ pdf = html.write_pdf(stylesheets=[CSS(settings.MEDIA_ROOT + '/pdf_gen.css')], presentational_hints=True)
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = 'inline; filename="invoice.pdf"'
return response
diff --git a/app/resume/admin.py b/app/resume/admin.py
index 93b186e..0a7594d 100644
--- a/app/resume/admin.py
+++ b/app/resume/admin.py
@@ -1,15 +1,23 @@
from django.contrib import admin
-from .models import Publisher, PubItem
+from .models import Publisher, PubItem, Job, Resume
-class PublisherAdmin(admin.ModelAdmin):
+@admin.register(Job)
+class JobAdmin(admin.ModelAdmin):
+ pass
+
+
+@admin.register(Resume)
+class ResumeAdmin(admin.ModelAdmin):
pass
+@admin.register(Publisher)
+class PublisherAdmin(admin.ModelAdmin):
+ pass
+
+@admin.register(PubItem)
class PubItemAdmin(admin.ModelAdmin):
list_display = ('title', 'pub_date', 'publisher', 'admin_link')
pass
-
-admin.site.register(Publisher, PublisherAdmin)
-admin.site.register(PubItem, PubItemAdmin)
diff --git a/app/resume/migrations/0004_job_resume.py b/app/resume/migrations/0004_job_resume.py
new file mode 100644
index 0000000..e056fec
--- /dev/null
+++ b/app/resume/migrations/0004_job_resume.py
@@ -0,0 +1,37 @@
+# Generated by Django 2.1.1 on 2019-01-12 12:45
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('resume', '0003_auto_20151211_1925'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Job',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(max_length=200)),
+ ('employer', models.CharField(max_length=200)),
+ ('date_start', models.DateField(verbose_name='Date Start')),
+ ('date_end', models.DateField(blank=True, null=True, verbose_name='Date End')),
+ ('body_markdown', models.TextField(blank=True, null=True)),
+ ],
+ options={
+ 'ordering': ('-date_end',),
+ },
+ ),
+ migrations.CreateModel(
+ name='Resume',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(max_length=200)),
+ ('profile', models.TextField()),
+ ('skills', models.TextField()),
+ ('experience', models.ManyToManyField(to='resume.Job')),
+ ],
+ ),
+ ]
diff --git a/app/resume/migrations/0005_job_slug.py b/app/resume/migrations/0005_job_slug.py
new file mode 100644
index 0000000..d18baeb
--- /dev/null
+++ b/app/resume/migrations/0005_job_slug.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.1.1 on 2019-01-12 12:56
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('resume', '0004_job_resume'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='job',
+ name='slug',
+ field=models.CharField(blank=True, max_length=50),
+ ),
+ ]
diff --git a/app/resume/migrations/0006_auto_20190112_1257.py b/app/resume/migrations/0006_auto_20190112_1257.py
new file mode 100644
index 0000000..9ee8f1b
--- /dev/null
+++ b/app/resume/migrations/0006_auto_20190112_1257.py
@@ -0,0 +1,22 @@
+# Generated by Django 2.1.1 on 2019-01-12 12:57
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('resume', '0005_job_slug'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='job',
+ name='slug',
+ ),
+ migrations.AddField(
+ model_name='resume',
+ name='slug',
+ field=models.CharField(blank=True, max_length=50),
+ ),
+ ]
diff --git a/app/resume/migrations/0007_auto_20190113_1128.py b/app/resume/migrations/0007_auto_20190113_1128.py
new file mode 100644
index 0000000..a635258
--- /dev/null
+++ b/app/resume/migrations/0007_auto_20190113_1128.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.1.1 on 2019-01-13 11:28
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('resume', '0006_auto_20190112_1257'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='job',
+ name='employer',
+ field=models.CharField(max_length=200, null=True),
+ ),
+ ]
diff --git a/app/resume/migrations/0008_auto_20190113_1139.py b/app/resume/migrations/0008_auto_20190113_1139.py
new file mode 100644
index 0000000..29d975d
--- /dev/null
+++ b/app/resume/migrations/0008_auto_20190113_1139.py
@@ -0,0 +1,24 @@
+# Generated by Django 2.1.1 on 2019-01-13 11:39
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('resume', '0007_auto_20190113_1128'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='resume',
+ old_name='experience',
+ new_name='jobs',
+ ),
+ migrations.AlterField(
+ model_name='job',
+ name='employer',
+ field=models.CharField(blank=True, default='', max_length=200),
+ preserve_default=False,
+ ),
+ ]
diff --git a/app/resume/migrations/0009_job_body_html.py b/app/resume/migrations/0009_job_body_html.py
new file mode 100644
index 0000000..fdeea15
--- /dev/null
+++ b/app/resume/migrations/0009_job_body_html.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.1.1 on 2019-01-13 11:46
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('resume', '0008_auto_20190113_1139'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='job',
+ name='body_html',
+ field=models.TextField(blank=True, null=True),
+ ),
+ ]
diff --git a/app/resume/migrations/0010_auto_20190113_1147.py b/app/resume/migrations/0010_auto_20190113_1147.py
new file mode 100644
index 0000000..879bd55
--- /dev/null
+++ b/app/resume/migrations/0010_auto_20190113_1147.py
@@ -0,0 +1,25 @@
+# Generated by Django 2.1.1 on 2019-01-13 11:47
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('resume', '0009_job_body_html'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='job',
+ name='body_html',
+ field=models.TextField(blank=True, default=''),
+ preserve_default=False,
+ ),
+ migrations.AlterField(
+ model_name='job',
+ name='body_markdown',
+ field=models.TextField(blank=True, default=''),
+ preserve_default=False,
+ ),
+ ]
diff --git a/app/resume/models.py b/app/resume/models.py
index 68f9a7e..390a277 100644
--- a/app/resume/models.py
+++ b/app/resume/models.py
@@ -1,6 +1,7 @@
from django.db import models
from django.utils.encoding import force_text
from django.urls import reverse
+from django.template.defaultfilters import slugify
from utils.util import markdown_to_html
@@ -53,3 +54,39 @@ class PubItem(models.Model):
if self.body_markdown:
self.body_html = markdown_to_html(self.body_markdown)
super(PubItem, self).save()
+
+
+class Job(models.Model):
+ title = models.CharField(max_length=200)
+ employer = models.CharField(max_length=200, blank=True)
+ date_start = models.DateField('Date Start')
+ date_end = models.DateField('Date End', null=True, blank=True)
+ body_markdown = models.TextField(blank=True)
+ body_html = models.TextField(blank=True)
+
+ class Meta:
+ ordering = ('-date_end',)
+
+ def __str__(self):
+ return '{} - {}'.format(self.title, self.employer) # py3.1+ only
+
+ def save(self, *args, **kwargs):
+ if self.body_markdown:
+ self.body_html = markdown_to_html(self.body_markdown)
+ super(Job, self).save()
+
+
+class Resume(models.Model):
+ title = models.CharField(max_length=200)
+ slug = models.CharField(max_length=50, blank=True)
+ profile = models.TextField()
+ skills = models.TextField()
+ jobs = models.ManyToManyField(Job)
+
+ def __str__(self):
+ return self.title
+
+ def save(self, *args, **kwargs):
+ if self._state.adding and not self.slug:
+ self.slug = slugify(self.title)
+ super(Resume, self).save()
diff --git a/app/resume/urls.py b/app/resume/urls.py
index 0d8b40a..47e07ad 100644
--- a/app/resume/urls.py
+++ b/app/resume/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls import url
+from django.urls import path, re_path
from django.views.generic.base import RedirectView
from . import views
@@ -6,34 +6,39 @@ from . import views
app_name = "resume"
urlpatterns = [
- url(
- r'pubs/(?P<page>\d+)/$',
+ path(
+ r'<str:slug>',
+ views.ResumeView.as_view(),
+ name='resume',
+ ),
+ path(
+ r'pubs/<str:page>/',
views.PublisherListView.as_view(),
name='list',
),
- url(
- r'pubs/(?P<publisher>[-\w]+)/(?P<page>\d+)/$',
+ path(
+ r'pubs/<str:publisher>/<str:page>/',
views.ByPublisherListView.as_view(),
name='list_by_publisher',
),
- url(
- r'pubs/(?P<publisher>[-\w]+)/(?P<slug>[-\w]+)$',
+ path(
+ r'pubs/<str:publisher>/<str:slug>',
views.PubItemDetailView.as_view(),
name='detail',
),
# redirect /slug/ to /slug/1/ for live server
- url(
+ path(
r'pubs/(?P<publisher>[-\w]+)/$',
RedirectView.as_view(url="/resume/pubs/%(publisher)s/1/", permanent=False),
name="live_publisher_redirect"
),
- url(
- r'pubs/$',
+ path(
+ r'pubs/',
RedirectView.as_view(url="/resume/pubs/1/", permanent=False),
name="live_redirect"
),
- url(
- r'^(?P<path>[-\w]+)(?:/(?P<slug>[-\w]+))$',
+ path(
+ r'<str:path>/<str:slug>',
views.PageView.as_view(),
name="pages"
),
diff --git a/app/resume/views.py b/app/resume/views.py
index 15acf14..9cdd8e7 100644
--- a/app/resume/views.py
+++ b/app/resume/views.py
@@ -2,7 +2,7 @@ from django.views.generic.detail import DetailView
from django.views.generic.base import TemplateView
from utils.views import PaginatedListView
-from .models import PubItem, Publisher
+from .models import PubItem, Publisher, Resume
from pages.models import Page
@@ -32,9 +32,10 @@ class ByPublisherListView(PaginatedListView):
context['publisher'] = Publisher.objects.get(slug=self.kwargs['publisher'])
return context
+
class PubItemDetailView(DetailView):
model = PubItem
- template_name = "details/resume.html"
+ template_name = "details/pubs.html"
slug_field = "slug"
@@ -51,3 +52,8 @@ class PageView(DetailView):
def get_template_names(self):
return ["details/%s.html" % self.object.slug, 'details/page.html']
+
+
+class ResumeView(DetailView):
+ model = Resume
+ template_name = "details/resume.html"
diff --git a/app/utils/util.py b/app/utils/util.py
index 6678fc9..714403b 100644
--- a/app/utils/util.py
+++ b/app/utils/util.py
@@ -110,3 +110,14 @@ def parse_video(s):
if soup.find('video'):
return True
return False
+
+def parse_reg_bio_page():
+ content = requests.get("https://www.theregister.co.uk/Author/Scott-Gilbertson/")
+ soup = BeautifulSoup(content, 'html.parser')
+ try:
+ image = soup.find_all('img')[0]['id']
+ img_pk = image.split('image-')[1]
+ return apps.get_model('photos', 'LuxImage').objects.get(pk=img_pk)
+ except IndexError:
+ return None
+