diff options
author | luxagraf <sng@luxagraf.net> | 2020-11-11 21:49:34 -0500 |
---|---|---|
committer | luxagraf <sng@luxagraf.net> | 2020-11-11 21:49:34 -0500 |
commit | 199184b3b680bc4c8878bf11a60c0fbf72fb612f (patch) | |
tree | 92195ea8a1ba5e61fefca51896c2b8e01cdeaf43 /app/unused_apps | |
parent | 129a8545b520380a8567a4e7405634250f3d7da5 (diff) |
removed some things I wasn't using to clean up code base
Diffstat (limited to 'app/unused_apps')
31 files changed, 1096 insertions, 0 deletions
diff --git a/app/unused_apps/income/__init__.py b/app/unused_apps/income/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/unused_apps/income/__init__.py diff --git a/app/unused_apps/income/admin.py b/app/unused_apps/income/admin.py new file mode 100644 index 0000000..b165371 --- /dev/null +++ b/app/unused_apps/income/admin.py @@ -0,0 +1,88 @@ +import datetime +from django.contrib import admin +from django.db.models import Sum +from django.contrib.gis.admin import OSMGeoAdmin +from django.conf.urls import url +from django.shortcuts import render + + +from .models import Gig, Invoice, InvoiceItem + + +@admin.register(InvoiceItem) +class InvoiceItemAdmin(admin.ModelAdmin): + list_display = ('time_start', 'time_end', 'work_done') + + +@admin.register(Invoice) +class InvoiceAdmin(admin.ModelAdmin): + list_display = ('title', 'admin_link', 'date_start', 'date_end') + + +@admin.register(Gig) +class GigAdmin(OSMGeoAdmin): + list_display = ('title', 'status', 'due_date', 'payment_status', 'payment', 'publisher', 'word_count') + list_filter = ('publisher', 'status', 'payment_status') + fieldsets = ( + ('Gig', { + 'fields': ( + 'title', + 'pitch', + ('created', 'due_date'), + ('payment', 'pay_type', 'payment_status', 'invoice_date'), + ('status', 'pub_date', 'word_count'), + 'publisher', + 'pub_item' + ), + 'classes': ( + 'show', + 'extrapretty', + 'wide' + ) + } + ), + ) + + def get_urls(self): + urls = super(GigAdmin, self).get_urls() + custom_urls = [ + url( + r'^monthly/$', + self.admin_site.admin_view(self.get_monthly), + name='monthly_admin' + ) + ] + return custom_urls + urls + + def get_monthly(self, request): + context = { + 'title': ("This month's income"), + 'app_label': self.model._meta.app_label, + 'opts': self.model._meta, + 'has_change_permission': self.has_change_permission(request) + } + try: + year = request.GET["m"].split("-")[0] + month = request.GET["m"].split("-")[1] + except: + year = datetime.datetime.now().strftime('%Y') + month = datetime.datetime.now().strftime('%m') + qs = self.model.objects.filter( + created__year=year, + created__month=month, + status__in=[1, 2, 3] + ) + context['pitched'] = self.model.objects.filter( + created__year=year, + created__month=month, + status=0 + ) + context['date'] = datetime.datetime.now() + context['billed'] = qs.filter(payment_status=1) + context['billed_total'] = qs.filter(payment_status=1).aggregate(total_payment=Sum('payment')) + context['unbilled'] = qs.filter(payment_status=0) + context['unbilled_total'] = qs.filter(payment_status=0).aggregate(total_payment=Sum('payment')) + context['total_outstanding'] = qs.aggregate(total_payment=Sum('payment')) + context['months'] = self.model.objects.dates('created', 'month') + return render(request, 'admin/income_month.html', context) + diff --git a/app/unused_apps/income/migrations/0001_initial.py b/app/unused_apps/income/migrations/0001_initial.py new file mode 100644 index 0000000..3a1e926 --- /dev/null +++ b/app/unused_apps/income/migrations/0001_initial.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-02-10 08:48 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('resume', '0003_auto_20151211_1925'), + ] + + operations = [ + migrations.CreateModel( + name='Gig', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=200)), + ('pitch', models.TextField(blank=True, null=True)), + ('created', models.DateTimeField(default=django.utils.timezone.now)), + ('pub_date', models.DateTimeField(default=django.utils.timezone.now)), + ('status', models.IntegerField(choices=[(0, 'Pitched'), (1, 'Accepted'), (2, 'Submitted'), (3, 'Published'), (4, 'Rejected'), (5, 'TO PITCH')], default=1)), + ('invoice_date', models.DateTimeField(blank=True, null=True)), + ('payment', models.DecimalField(decimal_places=2, max_digits=10)), + ('payment_status', models.IntegerField(choices=[(0, 'NOT SUBMITTED'), (1, 'Invoiced'), (2, 'Paid')], default=1)), + ('pay_type', models.IntegerField(choices=[(0, 'Flat Rate'), (1, 'Per Word'), (2, 'Hourly')], default=1)), + ('word_count', models.DecimalField(blank=True, decimal_places=0, max_digits=7, null=True)), + ('pub_item', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='resume.PubItem')), + ('publisher', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='resume.Publisher')), + ], + ), + ] diff --git a/app/unused_apps/income/migrations/0002_gig_due_date.py b/app/unused_apps/income/migrations/0002_gig_due_date.py new file mode 100644 index 0000000..ccd0f73 --- /dev/null +++ b/app/unused_apps/income/migrations/0002_gig_due_date.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-02-10 08:49 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('income', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='gig', + name='due_date', + field=models.DateField(default=django.utils.timezone.now), + ), + ] diff --git a/app/unused_apps/income/migrations/0003_auto_20161213_1038.py b/app/unused_apps/income/migrations/0003_auto_20161213_1038.py new file mode 100644 index 0000000..559cd5a --- /dev/null +++ b/app/unused_apps/income/migrations/0003_auto_20161213_1038.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-12-13 10:38 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('income', '0002_gig_due_date'), + ] + + operations = [ + migrations.AlterField( + model_name='gig', + name='due_date', + field=models.DateField(blank=True, null=True), + ), + migrations.AlterField( + model_name='gig', + name='pub_date', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/app/unused_apps/income/migrations/0004_invoice_invoiceitem.py b/app/unused_apps/income/migrations/0004_invoice_invoiceitem.py new file mode 100644 index 0000000..59f389c --- /dev/null +++ b/app/unused_apps/income/migrations/0004_invoice_invoiceitem.py @@ -0,0 +1,31 @@ +# Generated by Django 2.1 on 2018-09-03 17:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('income', '0003_auto_20161213_1038'), + ] + + operations = [ + migrations.CreateModel( + name='Invoice', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=200)), + ('date_start', models.DateField(blank=True, null=True)), + ('date_end', models.DateField(blank=True, null=True)), + ], + ), + migrations.CreateModel( + name='InvoiceItem', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time_start', models.DateTimeField(blank=True, null=True)), + ('time_end', models.DateTimeField(blank=True, null=True)), + ('work_done', models.TextField(blank=True, null=True)), + ], + ), + ] diff --git a/app/unused_apps/income/migrations/0005_invoice_slug.py b/app/unused_apps/income/migrations/0005_invoice_slug.py new file mode 100644 index 0000000..3b6dfb2 --- /dev/null +++ b/app/unused_apps/income/migrations/0005_invoice_slug.py @@ -0,0 +1,19 @@ +# Generated by Django 2.1.1 on 2018-09-03 19:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('income', '0004_invoice_invoiceitem'), + ] + + operations = [ + migrations.AddField( + model_name='invoice', + name='slug', + field=models.SlugField(default='slug'), + preserve_default=False, + ), + ] diff --git a/app/unused_apps/income/migrations/0006_auto_20190131_2351.py b/app/unused_apps/income/migrations/0006_auto_20190131_2351.py new file mode 100644 index 0000000..1c8f64c --- /dev/null +++ b/app/unused_apps/income/migrations/0006_auto_20190131_2351.py @@ -0,0 +1,17 @@ +# Generated by Django 2.1.1 on 2019-01-31 23:51 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('income', '0005_invoice_slug'), + ] + + operations = [ + migrations.AlterModelOptions( + name='invoiceitem', + options={'ordering': ('time_start',)}, + ), + ] diff --git a/app/unused_apps/income/migrations/__init__.py b/app/unused_apps/income/migrations/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/unused_apps/income/migrations/__init__.py diff --git a/app/unused_apps/income/models.py b/app/unused_apps/income/models.py new file mode 100644 index 0000000..e5a351b --- /dev/null +++ b/app/unused_apps/income/models.py @@ -0,0 +1,103 @@ +import datetime +from datetime import timedelta +from django.db import models +from django.utils import timezone +from django.urls import reverse +from django.utils.html import format_html + +from resume.models import PubItem, Publisher + + +class Gig(models.Model): + title = models.CharField(max_length=200) + pitch = models.TextField(null=True, blank=True) + created = models.DateTimeField(default=timezone.now) + pub_date = models.DateTimeField(blank=True, null=True) + due_date = models.DateField(blank=True, null=True) + STATUS = ( + (0, "Pitched"), + (1, "Accepted"), + (2, "Submitted"), + (3, "Published"), + (4, "Rejected"), + (5, "TO PITCH"), + ) + status = models.IntegerField(choices=STATUS, default=1) + invoice_date = models.DateTimeField(null=True, blank=True) + payment = models.DecimalField(max_digits=10, decimal_places=2) + PAY_STATUS = ( + (0, "NOT SUBMITTED"), + (1, "Invoiced"), + (2, "Paid"), + ) + payment_status = models.IntegerField(choices=PAY_STATUS, default=1) + PAY_TYPE = ( + (0, "Flat Rate"), + (1, "Per Word"), + (2, "Hourly"), + ) + pay_type = models.IntegerField(choices=PAY_TYPE, default=1) + word_count = models.DecimalField(max_digits=7, decimal_places=0, blank=True, null=True) + publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, blank=True, null=True) + pub_item = models.ForeignKey(PubItem, on_delete=models.CASCADE, blank=True, null=True) + + def __str__(self): + return self.title + + def get_pay_date(self): + days = self.publisher.payment_time * 7 + if self.invoice_date: + return self.invoice_date + datetime.timedelta(float(days)) + + +class Invoice(models.Model): + title = models.CharField(max_length=200) + slug = models.SlugField() + date_start = models.DateField(null=True, blank=True) + date_end = models.DateField(null=True, blank=True) + + def __str__(self): + return self.title + + def admin_link(self): + return format_html('<a href="/admin/income/invoice/monthlyview/%s/">View Invoice</a>' % (self.slug)) + admin_link.short_description = 'Invoice' + + +class InvoiceItem(models.Model): + time_start = models.DateTimeField(null=True, blank=True) + 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) + + @property + def total(self): + return self.time_end - self.time_start + + @property + def rounded_total(self): + """ + Rounds the given timedelta by the given timedelta period + :param td: `timedelta` to round + :param period: `timedelta` period to round by. + """ + period = timedelta(minutes=15) + td = self.total + period_seconds = period.total_seconds() + half_period_seconds = period_seconds / 2 + remainder = td.total_seconds() % period_seconds + if remainder >= half_period_seconds: + tdr = timedelta(seconds=td.total_seconds() + (period_seconds - remainder)) + hours, remainder = divmod(tdr.total_seconds(), 3600) + r = remainder/3600 + return float(hours)+r + else: + 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/unused_apps/income/parser.py b/app/unused_apps/income/parser.py new file mode 100644 index 0000000..b19d039 --- /dev/null +++ b/app/unused_apps/income/parser.py @@ -0,0 +1,23 @@ +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/unused_apps/income/views.py b/app/unused_apps/income/views.py new file mode 100644 index 0000000..1c34068 --- /dev/null +++ b/app/unused_apps/income/views.py @@ -0,0 +1,53 @@ +import datetime +from django.views.generic.detail import DetailView +from django.template.loader import render_to_string +from django.http import HttpResponse +from django.conf import settings + +#from weasyprint import HTML, CSS + +from .models import Invoice, InvoiceItem + + +class MonthlyInvoiceView(DetailView): + model = Invoice + template_name = "admin/income/monthly.html" + slug_field = "slug" + + def get_context_data(self, **kwargs): + context = super(MonthlyInvoiceView, self).get_context_data(**kwargs) + context['object_list'] = InvoiceItem.objects.filter(time_start__range=[self.object.date_start, self.object.date_end]) + total_time = [] + for item in context['object_list']: + total_time.append(item.rounded_total) + hours = (sum(total_time)) + context['total_hours'] = hours + context['total_billed'] = int(hours * 100) + context['invoice_number'] = self.object.id+21 + return context + + +class DownloadMonthlyInvoiceView(MonthlyInvoiceView): + model = Invoice + slug_field = "slug" + + def get(self, *args, **kwargs): + import logging + logger = logging.getLogger('weasyprint') + logger.addHandler(logging.FileHandler('weasyprint.log')) + self.object = self.get_object() # assign the object to the view + 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 + '/pdf_gen.css')], presentational_hints=True) + #response = HttpResponse(pdf, content_type='application/pdf') + #response['Content-Disposition'] = 'inline; filename="invoice.pdf"' + response = HttpResponse('', content_type='application/pdf') + return response diff --git a/app/unused_apps/people/__init__.py b/app/unused_apps/people/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/unused_apps/people/__init__.py diff --git a/app/unused_apps/people/admin.py b/app/unused_apps/people/admin.py new file mode 100644 index 0000000..ea0b463 --- /dev/null +++ b/app/unused_apps/people/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin +from .models import Person + + +@admin.register(Person) +class PersonAdmin(admin.ModelAdmin): + list_display = ('last_name', 'first_name', 'location_met', ) + diff --git a/app/unused_apps/people/build.py b/app/unused_apps/people/build.py new file mode 100644 index 0000000..35fdb19 --- /dev/null +++ b/app/unused_apps/people/build.py @@ -0,0 +1,35 @@ +import os +from django.urls import reverse +from builder.base import BuildNew + + +class BuildBooks(BuildNew): + + def build(self): + self.build_detail_view() + self.build_list_view( + base_path=reverse("books:live_redirect"), + paginate_by=24 + ) + print("building books") + + def get_model_queryset(self): + return self.model.objects.all() + + def build_detail_view(self): + ''' + write out all the expenses for each trip + ''' + for obj in self.get_model_queryset(): + url = obj.get_absolute_url() + path, slug = os.path.split(url) + path = '%s/' % path + # write html + response = self.client.get(url) + print(path, slug) + self.write_file(path, response.content, filename=slug) + + +def builder(): + j = BuildBooks("books", "book") + j.build() diff --git a/app/unused_apps/people/migrations/0001_initial.py b/app/unused_apps/people/migrations/0001_initial.py new file mode 100644 index 0000000..6f21bea --- /dev/null +++ b/app/unused_apps/people/migrations/0001_initial.py @@ -0,0 +1,42 @@ +# Generated by Django 2.0.1 on 2018-04-05 09:06 + +from django.db import migrations, models +import django.db.models.deletion +import taggit.managers + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('locations', '0003_auto_20180307_1027'), + ('taggit', '0002_auto_20150616_2121'), + ] + + operations = [ + migrations.CreateModel( + name='Person', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_name', models.CharField(max_length=200)), + ('last_name', models.CharField(max_length=200)), + ('email', models.EmailField(blank=True, max_length=120, null=True)), + ('street', models.CharField(blank=True, max_length=355, null=True)), + ('city', models.CharField(blank=True, max_length=200, null=True)), + ('state', models.CharField(blank=True, max_length=200, null=True)), + ('postal_code', models.CharField(blank=True, max_length=20, null=True)), + ('country', models.CharField(max_length=200, null=True)), + ('phone', models.CharField(blank=True, max_length=22, null=True)), + ('slug', models.CharField(blank=True, max_length=50)), + ('body_markdown', models.TextField(blank=True, null=True)), + ('body_html', models.TextField(blank=True, null=True)), + ('next_contact_date', models.DateField(blank=True, null=True)), + ('location_met', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='locations.Location')), + ('tags', taggit.managers.TaggableManager(blank=True, help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')), + ], + options={ + 'ordering': ('-last_name',), + }, + ), + ] diff --git a/app/unused_apps/people/migrations/__init__.py b/app/unused_apps/people/migrations/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/unused_apps/people/migrations/__init__.py diff --git a/app/unused_apps/people/models.py b/app/unused_apps/people/models.py new file mode 100644 index 0000000..1a07b16 --- /dev/null +++ b/app/unused_apps/people/models.py @@ -0,0 +1,54 @@ +from django.db import models +from django.template.defaultfilters import slugify + +from taggit.managers import TaggableManager +from locations.models import Location +from utils.util import markdown_to_html + + +class Person(models.Model): + first_name = models.CharField(max_length=200) + last_name = models.CharField(max_length=200) + email = models.EmailField(max_length=120, null=True, blank=True) + street = models.CharField(max_length=355, null=True, blank=True) + city = models.CharField(max_length=200, null=True, blank=True) + state = models.CharField(max_length=200, null=True, blank=True) + postal_code = models.CharField(max_length=20, null=True, blank=True) + country = models.CharField(max_length=200, null=True) + phone = models.CharField(max_length=22, blank=True, null=True) + slug = models.CharField(max_length=50, blank=True) + body_markdown = models.TextField(null=True, blank=True) + body_html = models.TextField(null=True, blank=True) + tags = TaggableManager(blank=True) + location_met = models.ForeignKey(Location, on_delete=models.CASCADE, null=True, blank=True) + next_contact_date = models.DateField(null=True, blank=True) + + class Meta: + ordering = ('-last_name',) + + def __str__(self): + return "%s %s" %(self.first_name, self.last_name) + + def get_absolute_url(self): + return reverse("people:detail", kwargs={"slug": self.slug}) + + @property + def get_previous_admin_url(self): + n = self.get_previous_by_pub_date() + return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[n.id] ) + + @property + def get_next_admin_url(self): + model = apps.get_model(app_label=self._meta.app_label, model_name=self._meta.model_name) + try: + return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[self.get_next_by_pub_date().pk] ) + except model.DoesNotExist: + return '' + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = slugify(("%s-%s")[:50] %(self.last_name, self.first_name)) + if self.body_markdown: + self.body_html = markdown_to_html(self.body_markdown) + super(Person, self).save() + diff --git a/app/unused_apps/people/urls.py b/app/unused_apps/people/urls.py new file mode 100644 index 0000000..0ae38eb --- /dev/null +++ b/app/unused_apps/people/urls.py @@ -0,0 +1,36 @@ +from django.urls import path, re_path +from django.views.generic.base import RedirectView + +from . import views + +app_name = "people" + +urlpatterns = [ + re_path( + r'^tag/(?P<slug>[-\w]+)/$', + views.PersonTagListView.as_view(), + {'page':1}, + name='list-tag' + ), + re_path( + r'tag/(?P<slug>[-\w]+)/(?P<page>\d+)/$', + views.PersonTagListView.as_view(), + name='list-tag' + ), + re_path( + r'^(?P<page>\d+)/$', + views.PersonListView.as_view(), + name="list" + ), + path( + r'', + views.PersonListView.as_view(), + {'page':1}, + name="list" + ), + path( + r'<str:slug>/', + views.PersonDetailView.as_view(), + name='detail', + ), +] diff --git a/app/unused_apps/people/views.py b/app/unused_apps/people/views.py new file mode 100644 index 0000000..36c0657 --- /dev/null +++ b/app/unused_apps/people/views.py @@ -0,0 +1,38 @@ +from django.views.generic.detail import DetailView +from utils.views import PaginatedListView + +from taggit.models import Tag +from .models import Person + + +class PersonListView(PaginatedListView): + model = Person + template_name = 'archives/people.html' + + def get_context_data(self, **kwargs): + # Call the base implementation first to get a context + context = super(PersonListView, self).get_context_data(**kwargs) + context['tags'] = Person.tags.all() + return context + + +class PersonDetailView(DetailView): + model = Person + template_name = "details/person.html" + slug_field = "slug" + + +class PersonTagListView(PaginatedListView): + model = Person + template_name = 'archives/people.html' + + def get_queryset(self): + print(self.kwargs['slug']) + return Person.objects.filter(tags__slug=self.kwargs['slug']) + + def get_context_data(self, **kwargs): + # Call the base implementation first to get a context + context = super(PersonTagListView, self).get_context_data(**kwargs) + context['tag'] = Tag.objects.get(slug__exact=self.kwargs['slug']) + context['tags'] = Person.tags.all() + return context diff --git a/app/unused_apps/stuff/__init__.py b/app/unused_apps/stuff/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/unused_apps/stuff/__init__.py diff --git a/app/unused_apps/stuff/admin.py b/app/unused_apps/stuff/admin.py new file mode 100644 index 0000000..135b17b --- /dev/null +++ b/app/unused_apps/stuff/admin.py @@ -0,0 +1,56 @@ +from django.contrib import admin +from .models import Item + + +@admin.register(Item) +class ItemAdmin(admin.ModelAdmin): + list_display = ( + 'title', + 'admin_thumbnail', + 'item_type', + 'creator', + 'purchase_price', + 'item_format', + 'isbn' + ) + list_filter = ['item_format', 'item_type'] + + fieldsets = ( + ('Item', { + 'fields': ( + 'title', + ('date_purchased', 'date_added'), + 'item_format', + 'purchase_price', + 'image', + 'item_type', + 'creator', + 'serial_number', + 'isbn', + ), + 'classes': ( + 'show', + 'extrapretty', + 'wide' + ) + } + ), + ('Extra', { + 'fields': ( + 'creator_sort_last_name', + 'creator_sort_first_name', + 'current_price', + 'retail_price', + 'amazon_url', + 'image_url', + ), + 'classes': ( + 'collapse', + 'extrapretty', + 'wide' + ) + }), + ) + + class Media: + js = ('image-loader.js', 'next-prev-links.js') diff --git a/app/unused_apps/stuff/models.py b/app/unused_apps/stuff/models.py new file mode 100644 index 0000000..05a7f4f --- /dev/null +++ b/app/unused_apps/stuff/models.py @@ -0,0 +1,65 @@ +from django.db import models +from django.urls import reverse +from django.utils.html import format_html +from django.utils import timezone +from django.conf import settings + + +class Item(models.Model): + isbn = models.CharField(max_length=100, blank=True, null=True) + serial_number = models.CharField(max_length=100, blank=True, null=True) + ITEM_TYPES = ( + (0, 'Book'), + (1, 'Apparel'), + (2, 'Gadget'), + (3, 'Furniture'), + ) + item_type = models.IntegerField(choices=ITEM_TYPES, default=0) + title = models.CharField(max_length=200) + creator = models.CharField(max_length=200, blank=True, null=True) + creator_sort_last_name = models.CharField(max_length=200, blank=True, null=True) + creator_sort_first_name = models.CharField(max_length=200, blank=True, null=True) + current_price = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True) + retail_price = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True) + purchase_price = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True) + amazon_url = models.CharField(max_length=400, blank=True, null=True) + image_url = models.CharField(max_length=400, blank=True, null=True) + image = models.FileField(upload_to='stuff/', null=True, blank=True) + item_format = models.CharField(max_length=255, blank=True, null=True) + date_released = models.DateTimeField(blank=True, null=True) + date_purchased = models.DateTimeField(blank=True, null=True, default=timezone.now) + date_added = models.DateTimeField(blank=True, null=True, default=timezone.now) + + class Meta: + ordering = ['-date_added'] + + def __str__(self): + return self.title + + @property + def get_previous_published(self): + return self.get_previous_by_date_added(status__exact=1) + + @property + def get_next_published(self): + return self.get_next_by_date_added(status__exact=1) + + @property + def get_previous_admin_url(self): + n = self.get_previous_by_date_added() + return reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name), args=[n.id]) + + @property + def get_next_admin_url(self): + model = apps.get_model(app_label=self._meta.app_label, model_name=self._meta.model_name) + try: + return reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name), args=[self.get_next_by_date_added().pk]) + except model.DoesNotExist: + return '' + + def get_image_url(self): + return '%s%s' % (settings.MEDIA_URL, self.image) + + def admin_thumbnail(self): + return format_html('<img src="%s" width="100" style="width:100px">' % (self.get_image_url())) + admin_thumbnail.short_description = 'Thumbnail' diff --git a/app/unused_apps/stuff/temp.py b/app/unused_apps/stuff/temp.py new file mode 100644 index 0000000..2150563 --- /dev/null +++ b/app/unused_apps/stuff/temp.py @@ -0,0 +1,115 @@ +from stuff.models import Item +from django.conf import settings +from datetime import datetime +from decimal import Decimal +import csv +item_types = { 'Book':0, 'Apparel': 1,'Gadget': 2, 'Furniture': 3} +""" +csv_file = csv.DictReader(open('stuff.csv', 'rb'), delimiter=',') +for line in csv_file: + if line['release date'][:-6] != '': + date_released = datetime.strptime(line['release date'][:-6], "%Y-%m-%d %H:%M:%S") + else: + date_released = None + if line['purchase date'][:-6] != '': + date_purchased = datetime.strptime(line['purchase date'][:-6], "%Y-%m-%d %H:%M:%S") + else: + date_purchased = None + if line['creation date'][:-6] != '': + date_added = datetime.strptime(line['creation date'][:-6], "%Y-%m-%d %H:%M:%S") + else: + date_added = None + item_type = int(item_types[line['item type']]) + if line['current value'][1:] != '': + try: + current_price = Decimal(line['current value'][1:].replace(",", "")) + except: + current_price = None + else: + current_price = None + if line['retail price'][1:] != '': + try: + retail_price = Decimal(line['retail price'][1:].replace(",", "")) + except: + retail_price =None + else: + retail_price =None + if line['purchase price'][1:] != '' and line['purchase price'] != "Gift": + try: + purchase_price = Decimal(line['purchase price'][1:].replace(",", "").replace('\\xa0', ' ')) + except: + purchase_price =None + else: + purchase_price =None + i, created = Item.objects.get_or_create( + isbn = line['ISBN'], + serial_number = line['serial number'], + type = item_type, + title = line['title'], + creator = line['creator'], + current_price = current_price, + retail_price = retail_price, + purchase_price = purchase_price, + amazon_url = line['amazon link'], + image_url = line['coverImageLargeURLString'], + format = line['format'], + date_released = date_released, + date_purchased = date_purchased, + date_added = date_added + ) + print created, i.title +""" +import datetime +import os +import io +import urllib + + +from django.contrib.contenttypes.models import ContentType +from django.template.defaultfilters import slugify +from django.core.exceptions import ObjectDoesNotExist +from django.conf import settings + +# Required PIL classes may or may not be available from the root namespace +# depending on the installation +try: + import Image + import ImageFile + import ImageFilter + import ImageEnhance +except ImportError: + try: + from PIL import Image + from PIL import ImageFile + from PIL import ImageFilter + from PIL import ImageEnhance + except ImportError: + raise ImportError("Could not import the Python Imaging Library.") + +ImageFile.MAXBLOCK = 1000000 + + +def grab_item_image(item): + crop_dir = settings.IMAGES_ROOT + '/stuff/' + if not os.path.isdir(crop_dir): + os.makedirs(crop_dir) + remote = item.image_url + try: + fname = urllib.request.urlopen(remote) + except: + return False + im = io.BytesIO(fname.read()) + img = Image.open(im) + ext = slugify(item.title)[:40] + filename = '%s/%s.jpg' %(crop_dir, ext) + try: + if img.format == 'JPEG': + img.save(filename, 'JPEG', quality=95, optimize=True) + else: + img.save(filename) + except IOError: + if os.path.isfile(filename): + os.unlink(filename) + pass + return 'images/stuff/%s.jpg'%(ext) + diff --git a/app/unused_apps/trips/__init__.py b/app/unused_apps/trips/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/unused_apps/trips/__init__.py diff --git a/app/unused_apps/trips/admin.py b/app/unused_apps/trips/admin.py new file mode 100644 index 0000000..54991f6 --- /dev/null +++ b/app/unused_apps/trips/admin.py @@ -0,0 +1,34 @@ +from django.contrib import admin +from django.contrib.gis.admin import OSMGeoAdmin + +from .models import Trip + +from utils.widgets import OLAdminBase +from utils.util import get_latlon +from utils.widgets import LGEntryForm + +@admin.register(Trip) +class TripAdmin(OSMGeoAdmin): + list_display = ('title', 'slug') + prepopulated_fields = {'slug': ('title',)} + ordering = ('title',) + search_fields = ['title'] + list_select_related = True + fieldsets = ( + ('Trip', { + 'fields': ( + 'title', + 'subtitle', + 'dek_markdown', + 'route', + 'slug', + 'start_date', + 'end_date', + 'pub_date', + ), + 'classes': ( + 'show', + 'extrapretty' + ) + }), + ) diff --git a/app/unused_apps/trips/migrations/0001_initial.py b/app/unused_apps/trips/migrations/0001_initial.py new file mode 100644 index 0000000..3d3c222 --- /dev/null +++ b/app/unused_apps/trips/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# Generated by Django 2.1.7 on 2019-06-15 09:17 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('locations', '0018_auto_20190414_2124'), + ] + + operations = [ + migrations.CreateModel( + name='Trip', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=50)), + ('subtitle', models.CharField(blank=True, max_length=200)), + ('slug', models.SlugField(unique_for_date='pub_date')), + ('dek_markdown', models.TextField()), + ('dek_html', models.TextField(blank=True, null=True)), + ('pub_date', models.DateTimeField(verbose_name='Date published')), + ('start_date', models.DateTimeField(verbose_name='Date started')), + ('end_date', models.DateTimeField(verbose_name='Date ended')), + ('route', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='locations.Route')), + ], + ), + ] diff --git a/app/unused_apps/trips/migrations/__init__.py b/app/unused_apps/trips/migrations/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/unused_apps/trips/migrations/__init__.py diff --git a/app/unused_apps/trips/models.py b/app/unused_apps/trips/models.py new file mode 100644 index 0000000..76941f2 --- /dev/null +++ b/app/unused_apps/trips/models.py @@ -0,0 +1,40 @@ +import json +import requests +from django import forms +from django.urls import reverse +from django.apps import apps +from django.contrib.gis.geos import GEOSGeometry, fromstr, MultiPolygon +from django.contrib.gis.db import models +from django.contrib.sitemaps import Sitemap +from django.utils.safestring import mark_safe +from django.utils import timezone +from django.conf import settings + +from utils.util import render_images, extract_main_image, markdown_to_html +from locations.models import Route + + +class Trip(models.Model): + """Model to define trips""" + title = models.CharField(max_length=50) + subtitle = models.CharField(max_length=200, blank=True) + slug = models.SlugField(unique_for_date='pub_date') + dek_markdown = models.TextField() + dek_html = models.TextField(null=True, blank=True) + pub_date = models.DateTimeField('Date published') + start_date = models.DateTimeField('Date started') + end_date = models.DateTimeField('Date ended') + route = models.ForeignKey(Route, on_delete=models.CASCADE) + + def get_absolute_url(self): + return "/trips/%s/" % (self.slug) + + def __str__(self): + return self.title + + def save(self, *args, **kwargs): + created = self.pk is None + if not created: + md = render_images(self.dek_markdown) + self.dek_html = markdown_to_html(md) + super(Trip, self).save(*args, **kwargs) diff --git a/app/unused_apps/trips/urls.py b/app/unused_apps/trips/urls.py new file mode 100644 index 0000000..205c450 --- /dev/null +++ b/app/unused_apps/trips/urls.py @@ -0,0 +1,24 @@ +from django.urls import path, re_path + +from . import views + +app_name = "trips" + +urlpatterns = [ + path( + r'<str:slug>', + views.LocationDetail.as_view(), + name="location-detail" + ), + path( + r'mapdata/', + views.MapDataList.as_view(), + name="mapdata" + ), + re_path(r'data/(?P<id>\d+)/$', views.data_json), + path( + r'', + views.MapList.as_view(), + name="maplist" + ), +] diff --git a/app/unused_apps/trips/views.py b/app/unused_apps/trips/views.py new file mode 100644 index 0000000..3a93c0d --- /dev/null +++ b/app/unused_apps/trips/views.py @@ -0,0 +1,101 @@ +from django.shortcuts import render_to_response +from django.template import RequestContext +from django.views.generic import ListView +from django.views.generic.detail import DetailView +from django.conf import settings +from django.db.models import Q + +from jrnl.models import Entry +from projects.shortcuts import render_to_geojson +from sightings.models import Sighting + +from .models import Country, Region, Route, Location + +def map_list(request): + context = { + 'object_list': Entry.objects.filter(status__exact=1), + 'country_list': Country.objects.filter(visited=True).exclude(name='default'), + 'route_list': Route.objects.all(), + 'region_list': Region.objects.all() + } + return render_to_response( + 'archives/map.html', + context, + context_instance=RequestContext(request) + ) + +class MapList(ListView): + """ + Return list of Entries on map + """ + context_object_name = 'object_list' + queryset = Entry.objects.filter(status__exact=1) + template_name = 'archives/map.html' + + def get_context_data(self, **kwargs): + # Call the base implementation first to get a context + context = super(MapList, self).get_context_data(**kwargs) + context['country_list'] = Country.objects.filter(visited=True).exclude(name='default'), + context['route_list'] = Route.objects.all(), + context['region_list'] = Region.objects.all() + context['IMAGES_URL'] = settings.IMAGES_URL + return context + + +class MapDataList(ListView): + """ + Build data file for Entries on map + """ + context_object_name = 'object_list' + queryset = Entry.objects.filter(status__exact=1) + template_name = 'archives/map_data.html' + + def get_context_data(self, **kwargs): + # Call the base implementation first to get a context + context = super(MapDataList, self).get_context_data(**kwargs) + context['country_list'] = Country.objects.filter(visited=True).exclude(name='default'), + context['route_list'] = Route.objects.all(), + context['region_list'] = Region.objects.all() + context['IMAGES_URL'] = settings.IMAGES_URL + return context + +def map_data(request): + context = { + 'object_list': Entry.objects.filter(status__exact=1), + 'route_list': Route.objects.all(), + 'country_list': Country.objects.filter(visited=True).exclude(name='default'), + 'region_list': Region.objects.all() + } + return render_to_response( + 'archives/map_data.html', + context, + context_instance=RequestContext(request) + ) + + +def data_json(request, id): + qs = Route.objects.filter(pk=id) + return render_to_geojson( + qs, + included_fields=['id', ], + geom_attribute='geometry', + mimetype='application/json', + pretty_print=True + ) + + +class LocationDetail(DetailView): + model = Location + template_name = "details/location.html" + + def get_context_data(self, **kwargs): + context = super(LocationDetail, self).get_context_data(**kwargs) + context['entry_list'] = Entry.objects.filter( + Q(location=self.get_object()) | + Q(location__in=Location.objects.filter(parent=self.get_object())) + ) + context['sighting_list'] = Sighting.objects.filter( + Q(location=self.get_object()) | + Q(location__in=Location.objects.filter(parent=self.get_object())) + ).order_by('ap_id', 'ap__apclass__kind').distinct("ap") + return context |