<commit_before>import sets
from datetime import datetime, timedelta

from django.db import connection
from django.contrib.auth.models import User
from apps.objects.models import Object, Attribute
import defines_global as defines_global
import gameconf

"""
Common database functions.
"""
def num_total_players():
   """
   Returns the total number of registered players.
   """
   return User.objects.count()

def get_connected_players():
   """
   Returns the a QuerySet containing the currently connected players.
   """
   return Object.objects.filter(nosave_flags__contains="CONNECTED")

def num_connected_players():
   """
   Returns the number of connected players.
   """
   return get_connected_players().count()

def num_recently_created_players(days=7):
   """
   Returns a QuerySet containing the player User accounts that have been
   connected within the last <days> days.
   """
   end_date = datetime.now()
   tdelta = timedelta(days)
   start_date = end_date - tdelta
   return User.objects.filter(date_joined__range=(start_date, end_date)).count()

def num_recently_connected_players(days=7):
   """
   Returns a QuerySet containing the player User accounts that have been
   connected within the last <days> days.
   """
   end_date = datetime.now()
   tdelta = timedelta(days)
   start_date = end_date - tdelta
   return User.objects.filter(last_login__range=(start_date, end_date)).count()

def is_unsavable_flag(flagname):
   """
   Returns TRUE if the flag is an unsavable flag.
   """
   return flagname.upper() in defines_global.NOSAVE_FLAGS

def is_modifiable_flag(flagname):
   """
   Check to see if a particular flag is modifiable.
   """
   if flagname.upper() not in defines_global.NOSET_FLAGS:
      return True
   else:
      return False
      
def is_modifiable_attrib(attribname):
   """
   Check to see if a particular attribute is modifiable.

   attribname: (string) An attribute name to check.
   """
   if attribname.upper() not in defines_global.NOSET_ATTRIBS:
      return True
   else:
      return False
      
def get_nextfree_dbnum():
   """
   Figure out what our next free database reference number is.
   
   If we need to recycle a GARBAGE object, return the object to recycle
   Otherwise, return the first free dbref.
   """
   # First we'll see if there's an object of type 6 (GARBAGE) that we
   # can recycle.
   nextfree = Object.objects.filter(type__exact=defines_global.OTYPE_GARBAGE)
   if nextfree:
      # We've got at least one garbage object to recycle.
      return nextfree[0]
   else:
      # No garbage to recycle, find the highest dbnum and increment it
      # for our next free.
      return int(Object.objects.order_by('-id')[0].id + 1)

def global_object_name_search(ostring, exact_match=False):
   """
   Searches through all objects for a name match.
   """
   if exact_match:
      return Object.objects.filter(name__iexact=ostring).exclude(type=defines_global.OTYPE_GARBAGE)
   else:
      return Object.objects.filter(name__icontains=ostring).exclude(type=defines_global.OTYPE_GARBAGE)
   
def list_search_object_namestr(searchlist, ostring, dbref_only=False, limit_types=False, match_type="fuzzy"):
   """
   Iterates through a list of objects and returns a list of
   name matches.
   searchlist: (List of Objects) The objects to perform name comparisons on.
   ostring:    (string) The string to match against.
   dbref_only: (bool) Only compare dbrefs.
   limit_types: (list of int) A list of Object type numbers to filter by.
   """
   if dbref_only:
      if limit_types:
         return [prospect for prospect in searchlist if prospect.dbref_match(ostring) and prospect.type in limit_types]
      else:
         return [prospect for prospect in searchlist if prospect.dbref_match(ostring)]
   else:
      if limit_types:
         return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type) and prospect.type in limit_types]
      else:
         return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type)]

def player_search(searcher, ostring):
   """
   Combines an aias and local/global search for a player's name.
   searcher: (Object) The object doing the searching.
   ostring:  (string) The alias string to search for.
   """
   alias_results = alias_search(searcher, ostring)
   if len(alias_results) > 0:
      return alias_results
   else:
      return local_and_global_search(searcher, ostring, limit_types=[defines_global.OTYPE_PLAYER])

def standard_plr_objsearch(session, ostring, search_contents=True, search_location=True, dbref_only=False, limit_types=False):
   """
   Perform a standard object search via a player session, handling multiple
   results and lack thereof gracefully.

   session: (SessionProtocol) Reference to the player's session.
   ostring: (str) The string to match object names against.
   """
   pobject = session.get_pobject()
   results = local_and_global_search(pobject, ostring, search_contents=search_contents, search_location=search_location, dbref_only=dbref_only, limit_types=limit_types)

   if len(results) > 1:
      session.msg("More than one match found (please narrow target):")
      for result in results:
         session.msg(" %s" % (result.get_name(),))
      return False
   elif len(results) == 0:
      session.msg("I don't see that here.")
      return False
   else:
      return results[0]

def object_totals():
   """
   Returns a dictionary with database object totals.
   """
   dbtotals = {}
   dbtotals["objects"] = Object.objects.count()
   dbtotals["things"] = Object.objects.filter(type=defines_global.OTYPE_THING).count()
   dbtotals["exits"] = Object.objects.filter(type=defines_global.OTYPE_EXIT).count()
   dbtotals["rooms"] = Object.objects.filter(type=defines_global.OTYPE_ROOM).count()
   dbtotals["garbage"] = Object.objects.filter(type=defines_global.OTYPE_GARBAGE).count()
   dbtotals["players"] = Object.objects.filter(type=defines_global.OTYPE_PLAYER).count()
   return dbtotals

def alias_search(searcher, ostring):
   """
   Search players by alias. Returns a list of objects whose "ALIAS" attribute
   exactly (not case-sensitive) matches ostring. If there isn't an alias match,
   perform a local_and_global_search().
   
   searcher: (Object) The object doing the searching.
   ostring:  (string) The alias string to search for.
   """<commit_msg>Updated some comments to make them a little more clear.<commit_after>import sets
from datetime import datetime, timedelta

from django.db import connection
from django.contrib.auth.models import User
from apps.objects.models import Object, Attribute
import defines_global as defines_global
import gameconf

"""
Common database functions.
"""
def num_total_players():
   """
   Returns the total number of registered players.
   """
   return User.objects.count()

def get_connected_players():
   """
   Returns the a QuerySet containing the currently connected players.
   """
   return Object.objects.filter(nosave_flags__contains="CONNECTED")

def num_connected_players():
   """
   Returns the number of connected players.
   """
   return get_connected_players().count()

def num_recently_created_players(days=7):
   """
   Returns a QuerySet containing the player User accounts that have been
   connected within the last <days> days.
   """
   end_date = datetime.now()
   tdelta = timedelta(days)
   start_date = end_date - tdelta
   return User.objects.filter(date_joined__range=(start_date, end_date)).count()

def num_recently_connected_players(days=7):
   """
   Returns a QuerySet containing the player User accounts that have been
   connected within the last <days> days.
   """
   end_date = datetime.now()
   tdelta = timedelta(days)
   start_date = end_date - tdelta
   return User.objects.filter(last_login__range=(start_date, end_date)).count()

def is_unsavable_flag(flagname):
   """
   Returns TRUE if the flag is an unsavable flag.
   """
   return flagname.upper() in defines_global.NOSAVE_FLAGS

def is_modifiable_flag(flagname):
   """
   Check to see if a particular flag is modifiable.
   """
   if flagname.upper() not in defines_global.NOSET_FLAGS:
      return True
   else:
      return False
      
def is_modifiable_attrib(attribname):
   """
   Check to see if a particular attribute is modifiable.

   attribname: (string) An attribute name to check.
   """
   if attribname.upper() not in defines_global.NOSET_ATTRIBS:
      return True
   else:
      return False
      
def get_nextfree_dbnum():
   """
   Figure out what our next free database reference number is.
   
   If we need to recycle a GARBAGE object, return the object to recycle
   Otherwise, return the first free dbref.
   """
   # First we'll see if there's an object of type 6 (GARBAGE) that we
   # can recycle.
   nextfree = Object.objects.filter(type__exact=defines_global.OTYPE_GARBAGE)
   if nextfree:
      # We've got at least one garbage object to recycle.
      return nextfree[0]
   else:
      # No garbage to recycle, find the highest dbnum and increment it
      # for our next free.
      return int(Object.objects.order_by('-id')[0].id + 1)

def global_object_name_search(ostring, exact_match=False):
   """
   Searches through all objects for a name match.
   """
   if exact_match:
      return Object.objects.filter(name__iexact=ostring).exclude(type=defines_global.OTYPE_GARBAGE)
   else:
      return Object.objects.filter(name__icontains=ostring).exclude(type=defines_global.OTYPE_GARBAGE)
   
def list_search_object_namestr(searchlist, ostring, dbref_only=False, limit_types=False, match_type="fuzzy"):
   """
   Iterates through a list of objects and returns a list of
   name matches.
   searchlist: (List of Objects) The objects to perform name comparisons on.
   ostring:    (string) The string to match against.
   dbref_only: (bool) Only compare dbrefs.
   limit_types: (list of int) A list of Object type numbers to filter by.
   """
   if dbref_only:
      if limit_types:
         return [prospect for prospect in searchlist if prospect.dbref_match(ostring) and prospect.type in limit_types]
      else:
         return [prospect for prospect in searchlist if prospect.dbref_match(ostring)]
   else:
      if limit_types:
         return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type) and prospect.type in limit_types]
      else:
         return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type)]

def player_search(searcher, ostring):
   """
   Combines an alias and local/global search for a player's name. If there are
   no alias matches, do a global search limiting by type PLAYER.
   
   searcher: (Object) The object doing the searching.
   ostring:  (string) The alias string to search for.
   """
   alias_results = alias_search(searcher, ostring)
   if len(alias_results) > 0:
      return alias_results
   else:
      return local_and_global_search(searcher, ostring, limit_types=[defines_global.OTYPE_PLAYER])

def standard_plr_objsearch(session, ostring, search_contents=True, search_location=True, dbref_only=False, limit_types=False):
   """
   Perform a standard object search via a player session, handling multiple
   results and lack thereof gracefully.

   session: (SessionProtocol) Reference to the player's session.
   ostring: (str) The string to match object names against.
   """
   pobject = session.get_pobject()
   results = local_and_global_search(pobject, ostring, search_contents=search_contents, search_location=search_location, dbref_only=dbref_only, limit_types=limit_types)

   if len(results) > 1:
      session.msg("More than one match found (please narrow target):")
      for result in results:
         session.msg(" %s" % (result.get_name(),))
      return False
   elif len(results) == 0:
      session.msg("I don't see that here.")
      return False
   else:
      return results[0]

def object_totals():
   """
   Returns a dictionary with database object totals.
   """
   dbtotals = {}
   dbtotals["objects"] = Object.objects.count()
   dbtotals["things"] = Object.objects.filter(type=defines_global.OTYPE_THING).count()
   dbtotals["exits"] = Object.objects.filter(type=defines_global.OTYPE_EXIT).count()
   dbtotals["rooms"] = Object.objects.filter(type=defines_global.OTYPE_ROOM).count()
   dbtotals["garbage"] = Object.objects.filter(type=defines_global.OTYPE_GARBAGE).count()
   dbtotals["players"] = Object.objects.filter(type=defines_global.OTYPE_PLAYER).count()
   return dbtotals

def alias_search(searcher, ostring):
   """
   Search players by alias. Returns a list of objects whose "ALIAS" attribute
   exactly (not case-sensitive) matches ostring.
   
   searcher: (Object) The object doing the searching.
   ostring:  (string) The alias string to search for.
   """
{'fraction_non_alphanumeric': 0.08980544747081712, 'fraction_numerical': 0.0015564202334630351, 'mean_word_length': 3.916220351951033, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3658527', 'n_tokens_mistral': 3912, 'n_tokens_neox': 3889, 'n_words': 1172}