123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- import logging
- import dateutil
- import os
- import re
- from datetime import datetime, timedelta
- from BeautifulSoup import BeautifulStoneSoup, BeautifulSoup
- from django.conf import settings
- from django.utils.html import strip_tags
- from django.db import models
- from django.db.models import permalink
- from django.utils.translation import ugettext_lazy as _
- from django.core.urlresolvers import reverse
- from django.contrib.auth.models import User
- import urllib
- #from darkroom.models import ImageModel
- from classifieds.managers import LiveManager, FeaturedManager
- from django_extensions.db.models import TimeStampedModel
- class Category(models.Model):
- """Category model."""
- name=models.CharField(_('name'), max_length=100)
- slug=models.SlugField(_('slug'), unique=True)
-
- class Meta:
- verbose_name=_('Category')
- verbose_name_plural=_('Categories')
- ordering=['name']
- def __unicode__(self):
- return self.name
- @models.permalink
- def get_absolute_url(self):
- return ('category_detail', (), {'slug': self.slug})
- class Subcategory(models.Model):
- '''Subcategory model.
- Really simple, just holds subcats for classified ads.
- For this app, objects only interact with subcats, not categories.
- '''
- name=models.CharField(_('Name'), max_length=100)
- number=models.IntegerField(_('Number'), max_length=4, blank=True, null=True)
- parent=models.ForeignKey(Category)
- slug=models.SlugField(_('slug'), unique=True)
- class Meta:
- verbose_name=_('Subcategory')
- verbose_name_plural=_('Subcategories')
- ordering=['parent', 'name']
- @property
- def active_ads(self):
- return self.classified_set.filter(expires_on__gte=datetime.now())
- def __unicode__(self):
- return self.name
- @models.permalink
- def get_absolute_url(self):
- return ('cl-subcategory-detail', (), {'slug': self.slug})
- '''
- class ClassifiedPhoto(ImageModel):
- image = models.ImageField(_('image'), upload_to='classifieds/images/')
- owner = models.ForeignKey(User)
- primary=models.BooleanField(_('primary'), default=False, help_text="Set this if you'd like the photo to appear on the main page when this ad is fetaured")
- def __unicode__(self):
- return self.title
- '''
- class Classified(TimeStampedModel):
- """Classified model."""
- STATUS_CHOICES=(
- (0, 'Standard'),
- (1, 'Plus'),
- )
- title=models.CharField(_('Title'), max_length=255, blank=True, null=True)
- #owner=models.ForeignKey(User, related_name='classifieds')
- copy=models.TextField(_('Copy'))
- #price=models.IntegerField(_('price'), null=True, blank=True)
- #photos = models.ManyToManyField(ClassifiedPhoto, blank=True)
- subcategory=models.ForeignKey(Subcategory)
- expires_on=models.DateField(_('Expires on'), default=(datetime.now()+timedelta(days=settings.CLASSIFIED_LENGTH)).date())
- #featured_until=models.DateField(_('featured until'), null=True, blank=True)
- featured=models.BooleanField(_('featured'), default=False)
- #status=models.IntegerField(_('status'), choices=STATUS_CHOICES,default=0)
-
- objects=models.Manager()
- live_objects=LiveManager()
- featured_objects=FeaturedManager()
-
- class Meta:
- verbose_name = _('classified')
- verbose_name_plural = _('classifieds')
- ordering = ('title',)
- get_latest_by='created'
- def __unicode__(self):
- if self.title:
- return u'%s' % (self.title)
- else:
- return u'%s' % (self.copy[0:30])
- class ClassifiedsUpload(models.Model):
- xml_file = models.FileField(_('xml file'), upload_to="temp",
- help_text=_('Select an xml (csv) exported ads file.'), blank=True, null=True)
- html_file = models.FileField(_('html file'), upload_to="temp",
- help_text=_('Select an html exported ads file.'), blank=True, null=True)
- class Meta:
- verbose_name = _('classifieds upload')
- verbose_name_plural = _('classifieds uploads')
-
- def save(self):
- super(ClassifiedsUpload, self).save()
- if self.xml_file:
- self.process_xmlfile()
- elif self.html_file:
- self.process_htmlfile()
- else:
- pass
- super(ClassifiedsUpload, self).delete()
-
- def process_xmlfile(self):
- xml = open(self.xml_file.path)
- soup = BeautifulStoneSoup(xml)
- n=0
- subcat=Subcategory.objects.get(name="Unclassified")
- for tag in soup.findAll('begad'):
- if n==0:
- pass
- else:
- next_week=datetime.now()+timedelta(days=7)
- ad = Classified(copy=unicode(tag.next), subcategory=subcat, expires_on=next_week)
- try:
- number=re.match('\<class:\d\d\d\>', str(tag.endad()[0])).group(0)[7:10]
- subcat=Subcategory.objects.get(number=int(number))
- except:
- pass
- ad.save()
- n+=1
- xml.close()
-
- def process_htmlfile(self):
- html = open(self.html_file.path)
- soup = BeautifulSoup(html)
- subcat = Subcategory.objects.get(number=999)
- next_week=datetime.now()+timedelta(days=8)
- for tag in soup.findAll('td'):
- try:
- if tag.attrs[0][1] == 'center':
- try:
- subcat = Subcategory.objects.get(number=int(tag.h2.string[:3]))
- except:
- subcat = Subcategory.objects.get(name="Unclassified")
- elif tag.attrs[0][1]=='left':
- copy=''
- for item in tag.contents:
- copy+=str(item)
- ad = Classified(copy=strip_tags(copy), subcategory=subcat, expires_on=next_week)
- ad.save()
- else:
- logging.info("Something went wrong while importing the following classified: %s" % strip_tags(copy))
- except:
- pass
- html.close()
-
|