Source code for SiteTracker.models

#    Eve W-Space
#    Copyright (C) 2013  Andrew Austin and other contributors
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version. An additional term under section
#    7 of the GPL is included in the LICENSE file.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
from django.db import models
from django.conf import settings
from Map.models import Map, System, MapSystem
from core.utils import get_config
from datetime import datetime
import pytz

# Create your models here.

User = settings.AUTH_USER_MODEL

[docs]class Fleet(models.Model): """Represents a SiteTracker fleet.""" system = models.ForeignKey(System, related_name="stfleets") initial_boss = models.ForeignKey(User, related_name="bossfleets") current_boss = models.ForeignKey(User, related_name="currently_bossing") started = models.DateTimeField(auto_now_add=True) ended = models.DateTimeField(blank=True, null=True) roles_needed = models.ManyToManyField('SiteRole', related_name="fleets_need") class Meta: permissions = (("can_sitetracker", "Use the Site Tracker system."),) def __unicode__(self): return u"MapSystem: %s Boss: %s Started: %s Ended: %s" % (self.system.name, self.current_boss.username, self.started, self.ended) def __contains__(self, user): """ Allow for user in fleet syntax to determine both inactive and active user records for a fleet. """ if user is None: return False return self.members.filter(user=user).exists() def __iter__(self): """ Provide support for syntax: for User in fleet """ for member_rec in self.members.all(): yield member_rec.user
[docs] def credit_site(self, site_type, system, boss): """ Credits a site. """ # Get the fleet member weighting variable and multiplier x = float(get_config("ST_SIZE_WEIGHT", None).value) n = self.members.count() if x > 1: weight_factor = x / float(n + (x - 1)) else: # If the factor is set to anything equal to or less than 1, # we will not weight the results by fleet size weight_factor = float(1) if SystemWeight.objects.filter(system=system).count(): weight_factor = weight_factor * system.st_weight.weight raw_points = SiteWeight.objects.get(site_type=site_type, sysclass=system.sysclass).raw_points site = SiteRecord(fleet=self, site_type=site_type, system=system, boss=boss, fleetsize=self.members.count(), raw_points=raw_points, weighted_points = raw_points * weight_factor) site.save() for user in self.members.filter(leavetime=None).all(): site.members.add(UserSite(site=site, user=user.user, pending=False)) return site
[docs] def close_fleet(self): """ Closes the SiteTracker fleet. """ for member in self.members.filter(leavetime=None): member.leavetime = datetime.now(pytz.utc) member.save() self.ended = datetime.now(pytz.utc) self.save()
[docs] def join_fleet(self, user): """ Adds user to fleet. """ if not self.members.filter(user=user, leavetime=None).count(): u = UserLog(fleet=self, user=user).save() else: u = self.members.get(user=user, leavetime=None) return u
[docs] def active_members(self): """ Return a list of active members. """ return self.members.filter(leavetime=None)
[docs] def leave_fleet(self, user): """ Removes user from fleet. """ if self.members.filter(leavetime=None).count() == 1: # We're the only member left, close the fleet. self.close_fleet() return None elif self.current_boss == user: # We're the boss, give it to the first schmuck we can. self.current_boss = self.members.exclude(user=user).filter( leavetime=None).all()[0].user self.save() UserLog.objects.filter(fleet=self, user=user, leavetime=None).update(leavetime=datetime.now(pytz.utc))
[docs] def make_boss(self, user): """ Change the current fleet boss. """ self.current_boss = user self.save()
[docs]class SiteRole(models.Model): """Represents a role for a sitetracker fleet.""" short_name = models.CharField(max_length=32, unique=True) long_name = models.CharField(max_length=255, unique=True)
[docs]class SiteType(models.Model): """Represents a type of site that can be credited.""" shortname = models.CharField(max_length=8, unique=True) longname = models.CharField(max_length=80, unique=True) # Defunct site types are maintained in the databse for relational purposes but can no longer be credited defunct = models.BooleanField(default=False) def __unicode__(self): return self.longname
[docs]class SiteWeight(models.Model): """ Represents the raw points available for a site type / system class combo """ site_type = models.ForeignKey(SiteType, related_name='weights') sysclass = models.IntegerField(choices=[(1, "C1"), (2, "C2"), (3, "C3"), (4, "C4"), (5, "C5"), (6, "C6"), (7, "High Sec"), (8, "Low Sec"), (9, "Null Sec")]) raw_points = models.IntegerField()
[docs]class SystemWeight(models.Model): """ Respresents a multiplier for site credit for a system. """ system = models.OneToOneField(System, primary_key=True, related_name='st_weight') weight = models.FloatField()
[docs]class SiteRecord(models.Model): """Represents the record of a site run.""" fleet = models.ForeignKey(Fleet, related_name="sites") site_type = models.ForeignKey(SiteType, related_name="sitesrun") timestamp = models.DateTimeField(auto_now_add=True) system = models.ForeignKey(System, related_name="sitescompleted") boss = models.ForeignKey(User, related_name="sitescredited") fleetsize = models.IntegerField() raw_points = models.IntegerField() weighted_points = models.FloatField() def __unicode__(self): return u"System: %s Time: %s Type: %s" % (self.system.name, self.timestamp, self.type.shortname) def __contains__(self, user): """ Allow for if user in siterecord to determine if a user has an entry. """ if user is None: return False return self.members.filter(user=user).exists() def __iter__(self): """ Allow for syntax: for user in siterecord. """ for log in self.members.all(): yield log.user
[docs] def is_pending(self, user): """ Return True if user's credit is pending. """ return self.members.get(user=user).pending
[docs]class UserSite(models.Model): """Represents a user's credit for a site.""" site = models.ForeignKey(SiteRecord, related_name="members") user = models.ForeignKey(User, related_name="sites") pending = models.BooleanField(default=False)
[docs] def approve(self): """ Mark the site approved. """ self.pending = False self.save()
[docs]class UserLog(models.Model): """Represents a user's sitetracker log.""" fleet = models.ForeignKey(Fleet, related_name="members") user = models.ForeignKey(User, related_name="sitetrackerlogs") jointime = models.DateTimeField(auto_now_add=True) leavetime = models.DateTimeField(null=True, blank=True)
[docs] def pending_sites(self): """ Returns a list of site records which are pending credit. """ pending_sites = [] for site in self.fleet.sites.all(): if UserSite.objects.filter(user=self.user, site=site, pending=True).exists(): pending_sites.append(site) return pending_sites
[docs]class ClaimPeriod(models.Model): """Represents a claim period that Users can claim against.""" starttime = models.DateTimeField() endtime = models.DateTimeField() name = models.CharField(max_length = 80) closetime = models.DateTimeField(blank=True, null=True) loothauledby = models.ForeignKey(User, related_name="loothauled", null=True, blank=True) lootsoldby = models.ForeignKey(User, related_name="lootsold", null=True, blank=True) class Meta: permissions = (("can_close_claims", "Close the claims period early."), ("can_reopen_claims", "Reopen the claims period."), ("can_haul_loot", "Mark the claim period as hauled."), ("can_sell_loot", "Mark the claim period as sold."),) def __unicode__(self): return self.name
[docs]class Claim(models.Model): """Represents a User's claim for a claim period.""" period = models.ForeignKey(ClaimPeriod, related_name="claims") user = models.ForeignKey(User, related_name="claims") shareclaimed = models.FloatField() description = models.TextField() bonus = models.FloatField(blank=True, null=True)
[docs]class PayoutReport(models.Model): """Represents a payout report and contains general information about the payout period.""" period = models.ForeignKey(ClaimPeriod, related_name="reports") createdby = models.ForeignKey(User, related_name="payoutreports") grossprofit = models.BigIntegerField() datepaid = models.DateTimeField(blank=True, null=True)
[docs]class PayoutEntry(models.Model): """Represents an entry in the payout report.""" report = models.ForeignKey(PayoutReport, related_name="entries") user = models.ForeignKey(User, related_name="payouts") claim = models.ForeignKey(Claim, related_name="payout") iskshare = models.BigIntegerField()