# -*- coding: utf-8 -*-
from django.db import models
from django.template.defaultfilters import truncatechars
from django.utils import timezone
from simhash import Simhash
import random
import uuid

import django.db.models.options as options
options.DEFAULT_NAMES = options.DEFAULT_NAMES + ('in_db',)

language_list = ['en', 'af', 'an', 'bs', 'ca', 'cs', 'cy', 'da', 'de', 'el', 'eo', 'es', 'et', 'eu', 'fi', 'fo', 'fr', 'ga', 'gl', 'ha', 'hr', 'hu', 'is', 'it', 'la', 'lb', 'lt', 'lv', 'mg', 'mt', 'nl', 'no', 'oc', 'pl', 'pt', 'qu', 'ro', 'rw', 'sk', 'sl', 'sn', 'so', 'sv', 'sw', 'tr', 'vo', 'wa', 'wo', 'xh', 'yo', 'zu']
hidden_language_list = ['vo', ]

# Only including languages that aren't also a valid country. This means that "ar", which could be argentina,
# and "uk" which could be the united kingdom, are not listed as blocked. Doing so could cause it to auto-delete
# some sites in English or Spanish.
blocked_language_list = ['am', 'ar', 'as', 'az', 'be', 'bg', 'bn', 'cn', 'dz', 'fa', 'gu', 'he',
                         'hi', 'hy', 'id', 'ja', 'jv', 'ka', 'kk', 'km', 'kn', 'ko', 'ku', 'ky',
                         'lo', 'mk', 'ml', 'mn', 'mr', 'ms', 'ne', 'or', 'pa', 'ps', 'ru', 'si',
                         'sq', 'sr', 'ta', 'te', 'th', 'tl', 'ug', 'uk', 'ur', 'vi', 'zh']

language_names = {
'af': 'Afrikaans',
'an': 'Aragonese',
'bs': 'Bosnian',
'ca': 'Catalan',
'cs': 'Czech',
'cy': 'Welsh',
'da': 'Danish',
'de': 'German',
'el': 'Greek',
'en': 'English',
'eo': 'Esperanto',
'et': 'Estonian',
'eu': 'Basque',
'es': 'Spanish',
'fi': 'Finnish',
'fo': 'Faroese',
'fr': 'French',
'ga': 'Irish',
'gl': 'Galician',
'ha': 'Hausa',
'hr': 'Croatian',
'hu': 'Hungarian',
'is': 'Icelandic',
'it': 'Italian',
'la': 'Latin',
'lb': 'Luxembourgish',
'lt': 'Lithuanian',
'lv': 'Latvian',
'mg': 'Malagasy',
'mt': 'Maltese',
'nl': 'Dutch',
'no': 'Norwegian',
'oc': 'Occitan',
'pl': 'Polish',
'pt': 'Portuguese',
'qu': 'Quechua',
'tr': 'Turkish',
'ro': 'Romanian',
'rw': 'Rwandan',
'sk': 'Slovakian',
'sl': 'Slovene',
'sv': 'Swedish',
'sw': 'Swahili',
'sn': 'Shona',
'so': 'Somali',
'vo': 'Volapuk',
'wa': 'Walloon',
'wo': 'Wolof',
'xh': 'Xhosa',
'yo': 'Yoruba',
'zu': 'Zulu',
}

blocked_language_names = {
'arabic': 'ar',
'armenian': 'am',
'assamese': 'as',
'azerbaijani': 'az',
'belarusian': 'be',
'bengali': 'bn',
'bulgarian': 'bg',
'burmese': 'my',
'chinese': 'zh',
'dzongkha': 'dz',
'farsi': 'fa',
'georgian': 'ge',
'hebrew': 'he',
'hindi': 'hi',
'indonesian': 'id',
'japanese': 'ja',
'javanese': 'jv',
'kannada': 'kn',
'kazakh': 'kk',
'khmer': 'km',
'korean': 'ko',
'kurdish': 'ku',
'lao': 'lo',
'macedonian': 'mk',
'malay': 'ms',
'malayalam': 'ml',
'marathi': 'mr',
'mongolian': 'mn',
'nepali': 'ne',
'oriya': 'or',
'punjabi': 'pa',
'pashto': 'ps',
'persian': 'fa',
'russian': 'ru',
'serbian': 'sr',
'sinhala': 'si',
'tagalog': 'tl',
'tamil': 'ta',
'telugu': 'te',
'thai': 'th',
'ukranian': 'uk',
'uyghur': 'ug',
'urdu': 'ur',
'vietnamese': 'vi',
}

month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']

EXCLUDED_SITE_REASONS = (
        # Anything by Demand Media or any sites that use similar tactics.
        (0, 'Content Farm'),
        # Sites that just aggregate or copy the content from other sites, i.e. Digg.
        (1, 'Aggregator or Meta Site'),
        # Social media sites like Facebook, Twitter, etc.
        (2, 'Social'),
        # Bait-and-switch sites that obfuscate content but still make it search-engine-able, like ExpertSexChange.com.
        (3, 'Bait and Switch'),
        # Adult website - we don't index those.
        (4, 'Porn or Adult Content'),
        # Pills/pharmacy.
        (5, 'Pills'),
        # Gambling
        (6, 'Online Gambling'),
        # Autogenerated site or otherwise overrun with spambots.
        (7, 'Spam or Computer Generated Content'),
        # Not a language we include in our index.
        (8, 'Unindexed Language - Unspecified'),
        (37, 'Unindexed Language - Albanian'),
        (45, 'Unindexed Language - Amharic'),
        (20, 'Unindexed Language - Arabic or Farsi'),
        (32, 'Unindexed Language - Armenian'),
        (50, 'Unindexed Language - Assamese'),
        (34, 'Unindexed Language - Azerbaijani'),
        (59, 'Unindexed Language - Belarusian'),
        (60, 'Unindexed Language - Bangladeshi'),
        (21, 'Unindexed Language - Chinese'),
        (56, 'Unindexed Language - Dzongkha'),
        (31, 'Unindexed Language - Georgian'),
        (46, 'Unindexed Language - Gujarati'),
        (22, 'Unindexed Language - Hebrew'),
        (23, 'Unindexed Language - Hindi'),
        (24, 'Unindexed Language - Indonesian or Similar'),
        (25, 'Unindexed Language - Japanese'),
        (49, 'Unindexed Language - Javanese'),
        (58, 'Unindexed Language - Kannada'),
        (43, 'Unindexed Language - Kazakh'),
        (26, 'Unindexed Language - Khmer'),
        (27, 'Unindexed Language - Korean'),
        (44, 'Unindexed Language - Kyrgyz'),
        (47, 'Unindexed Language - Kurdish'),
        (54, 'Unindexed Language - Lao'),
        (41, 'Unindexed Language - Macedonian'),
        (55, 'Unindexed Language - Marathi'),
        (61, 'Unindexed Language - Malayalam'),
        (48, 'Unindexed Language - Mongolian'),
        (52, 'Unindexed Language - Nepali'),
        (57, 'Unindexed Language - Oriya'),
        (39, 'Unindexed Language - Punjabi'),
        (40, 'Unindexed Language - Pashto'),
        (28, 'Unindexed Language - Russian or Other Cyrillic'),
        (33, 'Unindexed Language - Serbian'),
        (36, 'Unindexed Language - Sinhala'),
        (38, 'Unindexed Language - Tagalog'),
        (51, 'Unindexed Language - Tamil'),
        (42, 'Unindexed Language - Telugu'),
        (30, 'Unindexed Language - Thai'),
        (53, 'Unindexed Language - Uighur'),
        (35, 'Unindexed Language - Urdu'),
        (29, 'Unindexed Language - Vietnamese'),
        # Warez/torrent/crack/piracy sites.
        (9, 'Piracy'),
        (80, 'Undesirable Site'),  # Jerks who reported us to IP abuse sites or said bad things in general.
        # Sites that encourage human rights violations, racism, general douchebaggery.
        (10, 'Human Rights Abuses'),
        # This isn't a web site - it's an ad server.
        (11, 'Ad Server'),
        # URL shortener. Not actual content.
        (12, 'URL Shortener'),
        # No content. Not any actual content on this site.
        (13, 'No Content'),
        # No content. Not any actual content on this site.
        (14, 'Malware'),
        # BEGIN SITE RANK INCREASE REASONS - DON'T USE FOR BLOCKING
        # High-Quality Content
        (200, 'Quality Content'),
        # Partner site (or owned site)
        (201, 'Partner Site'),
)

RANK_ADJUSTMENTS = (
    (-3, 'Bottom'),
    (-2, 'Much Lower'),
    (-1, 'Slightly Lower'),
    (-4, 'Marginally Lower'),
    (0, 'Normal'),
    (1, 'Slightly Higher'),
    (2, 'Much Higher'),
)

PRIORITY_CHOICES = (
    (0, 'Highest'),
    (1, 'High'),
    (2, 'Medium'),
    (3, 'Low'),
    (4, 'Lowest')
)


class BlockedSite(models.Model):
    url = models.TextField(blank=False, unique=True, db_index=True)
    reason = models.IntegerField(null=True, blank=True, choices=EXCLUDED_SITE_REASONS)
    detailedreason = models.TextField(blank=True)
    exclude_subdomains = models.BooleanField(default=False, blank=True)
    date_added = models.DateTimeField(auto_now_add=True, db_index=True)

    class Meta:
        in_db = 'indexes'

    def __str__(self):
        return self.url

    def save(self, remove=True, *args, **kwargs):
        if remove:
            from dir.utils import RemoveURLsForDomain
            RemoveURLsForDomain(self.url)
            # Delete any URLs that use that scheme if they are in the database.
        super(BlockedSite, self).save(*args, **kwargs)


class IPAddress(models.Model):
    ip = models.CharField(max_length=16, blank=False, null=False, unique=True)
    spam_commenter = models.BooleanField(default=False, blank=True)
    date_added = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)

    class Meta:
        in_db = 'indexes'


class BadQuery(models.Model):
    """
    Represents a search request that should be considered a "bad request" and return a 400 error.

    This is used to discourage spambots and short-circuit their requests and prevent them from
    hitting the search index.

    We may want to expand this to include wildcards at some point. For now, we're just blocking
    individual phrases.
    """
    keywords = models.CharField(max_length=260, null=False, unique=True)
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.keywords

    class Meta:
        in_db = 'indexes'
        ordering = ['keywords', ]


class URLInfo(models.Model):
    rooturl = models.CharField(max_length=260, blank=True, null=False)
    url = models.CharField(max_length=2048, blank=True, null=False, unique=True)
    pagetitle = models.CharField(max_length=260, blank=True, null=True)
    pagedescription = models.CharField(max_length=320, blank=True, null=True)
    pagefirstheadtag = models.CharField(max_length=260, blank=True, null=True)
    pagefirsth2tag = models.CharField(max_length=260, blank=True, null=True)
    pagefirsth3tag = models.CharField(max_length=260, blank=True, null=True)
    pagekeywords = models.CharField(max_length=260, blank=True, null=True)
    pagetext = models.TextField(blank=True, null=True)
    pagesize = models.IntegerField(null=True, blank=True)
    lastcrawled = models.DateTimeField(null=True, blank=True)
    firstcrawled = models.DateTimeField(null=True, blank=True)  # Note that this won't be accurate for pages recrawled before 2015-09-22.
    ip = models.CharField(max_length=16, blank=True, null=True, db_index=True)
    num_errors = models.IntegerField(blank=True, default=0)
    error_info = models.TextField(blank=True, default='')
    server_header = models.CharField(max_length=128, null=True, blank=True)
    content_type_header = models.CharField(max_length=100, null=True, blank=True)
    num_css_files = models.IntegerField(null=True, blank=True, help_text='Number of external CSS files.')
    num_images = models.IntegerField(null=True, blank=True)
    num_javascripts = models.IntegerField(null=True, blank=True, help_text='Number of external JavaScript files.')
    num_iframes = models.IntegerField(null=True, blank=True)
    num_audio_tags = models.IntegerField(null=True, blank=True)
    num_video_tags = models.IntegerField(null=True, blank=True)
    num_svg_tags = models.IntegerField(null=True, blank=True)
    num_canvas_tags = models.IntegerField(null=True, blank=True)
    image_alt_tags = models.TextField(null=True, blank=True)
    image_title_tags = models.TextField(null=True, blank=True)
    image_filenames = models.TextField(null=True, blank=True)
    simhash_value = models.CharField(max_length=128, null=True, blank=True, db_index=True)

    def delete(self, keep_links=False):
        """
        Deletes any outgoing page links when a page is deleted.

        If keep_links is True, we don't delete the links. This is something that
        should be used when moving the site, for instance from the English index
        to the German index.
        """
        if not keep_links:
            links = PageLink.objects.filter(url_source=self.url)
            for link in links:
                link.delete()
            links = PageJavaScript.objects.filter(url_source=self.url)
            for link in links:
                link.delete()
            links = PageIFrame.objects.filter(url_source=self.url)
            for link in links:
                link.delete()
        super(URLInfo, self).delete()

    def save(self, *args, **kwargs):
        # Sets a new random value every time the link is saved.
        if self.pagetext and len(self.pagetext) > 0:
            hashval = Simhash(self.pagetext, f=128).value
        else:
            hashval = 0
        self.simhash_value = '{:0128b}'.format(hashval)
        super(URLInfo, self).save(*args, **kwargs)

    @property
    def short_url(self):
        return truncatechars(self.url, 120)

    class Meta:
        abstract = True


class SiteInfo(URLInfo):
    class Meta:
        db_table = 'site_info'

    def __str__(self):
        return self.url


class DomainInfo(models.Model):
    url = models.CharField(max_length=255, unique=True, db_index=True)
    language_association = models.CharField(max_length=8, null=True, blank=True)
    notes = models.TextField(null=True, blank=True)
    rank_adjustment = models.IntegerField(null=False, blank=True, default=0, choices=RANK_ADJUSTMENTS)
    rank_reason = models.IntegerField(null=True, blank=True, choices=EXCLUDED_SITE_REASONS)
    alexa_rank = models.IntegerField(null=True, blank=True)
    alexa_rank_date = models.DateField(null=True, blank=True)
    alexa_outdated = models.BooleanField(blank=True, default=False, db_index=True)
    majestic_rank = models.IntegerField(null=True, blank=True)
    majestic_refsubnets = models.IntegerField(null=True, blank=True)
    majestic_rank_date = models.DateField(null=True, blank=True)
    majestic_outdated = models.BooleanField(blank=True, default=False, db_index=True)
    quantcast_rank = models.IntegerField(null=True, blank=True)
    quantcast_rank_date = models.DateField(null=True, blank=True)
    quantcast_outdated = models.BooleanField(blank=True, default=False, db_index=True)
    domcop_rank = models.IntegerField(null=True, blank=True)
    domcop_pagerank = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=4)
    domcop_pagerank_date = models.DateField(null=True, blank=True)
    domcop_pagerank_outdated = models.BooleanField(blank=True, default=False, db_index=True)
    uses_language_subdirs = models.BooleanField(default=False, blank=True)
    uses_language_query_parameter = models.BooleanField(default=False, blank=True, help_text='Does this domain use query parameters like "hl=en" to determine the language?')
    uses_langid = models.BooleanField(default=False, blank=True, help_text='Does this domain use langid to categorize individual pages?')
    is_unblockable = models.BooleanField(blank=True, default=False, help_text='Is this domain unblockable, even by an idiot?')
    domain_created = models.DateTimeField(null=True, blank=True)
    domain_expires = models.DateTimeField(null=True, blank=True)
    domain_updated = models.DateTimeField(null=True, blank=True)  # The last time the whois server says the domain was updated.
    whois_last_updated = models.DateTimeField(null=True, blank=True)
    robots_ip = models.CharField(max_length=16, null=True, blank=True, db_index=True, help_text='The IP address of the server we retrieved (or tried to retrieve) the robots.txt from.')
    robots_txt = models.TextField(null=True, blank=True)
    robots_last_updated = models.DateTimeField(null=True, blank=True)
    domains_linking_in = models.IntegerField(null=True, blank=True)
    domains_linking_in_last_updated = models.DateTimeField(null=True, blank=True)
    # This domain has been verified as not porn, so don't suggest it's porn when scanning,
    # and ignore all attempts to pornblock it.
    verified_notporn = models.BooleanField(blank=True, default=False)
    # Only crawl the root url. With or without slash.
    num_urls = models.IntegerField(null=True, blank=True)
    num_urls_last_updated = models.DateField(null=True, blank=True)
    num_keywords_ranked = models.IntegerField(null=True, blank=True)
    num_keywords_last_updated = models.DateField(null=True, blank=True)
    favicons_last_updated = models.DateField(null=True, blank=True)
    whois_name = models.CharField(max_length=90, null=True, blank=True)
    whois_city = models.CharField(max_length=40, null=True, blank=True)
    whois_country = models.CharField(max_length=40, null=True, blank=True)
    whois_state = models.CharField(max_length=40, null=True, blank=True)
    whois_address = models.CharField(max_length=120, null=True, blank=True)
    whois_org = models.CharField(max_length=100, null=True, blank=True)
    whois_registrar = models.CharField(max_length=60, null=True, blank=True)
    whois_zipcode = models.CharField(max_length=40, null=True, blank=True)
    whois_nameservers = models.TextField(null=True, blank=True)
    whois_emails = models.TextField(null=True, blank=True)
    last_updated = models.DateTimeField(auto_now=True, null=True, blank=True)

    def __str__(self):
        return self.url


class Screenshot(models.Model):
    domain = models.OneToOneField('DomainInfo', db_index=True, unique=True)
    file_large = models.TextField(null=True, blank=True, help_text='1280x800px image file location.')
    file_small = models.TextField(null=True, blank=True, help_text='320x200px image file location.')
    date_taken = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.domain.url


class Favicon(models.Model):
    domain = models.ForeignKey('DomainInfo', db_index=True)
    date_taken = models.DateTimeField(auto_now_add=True)
    icon = models.TextField(null=False, blank=False)
    format = models.CharField(max_length=6, null=False, blank=False)
    width = models.IntegerField()
    height = models.IntegerField()

    def __str__(self):
        return self.domain.url


class AllowedDomain(models.Model):
    """
    When the crawler is in allowed-domain-only mode, this controls what domains can be added
    to the index and the pending URL list.

    All other settings are controlled by the DomainInfo class.
    """
    url = models.CharField(max_length=255, unique=True, db_index=True)

    def __str__(self):
        return self.url


class DomainSuffix(models.Model):
    extension = models.CharField(max_length=30, null=False, blank=False, db_index=True)
    num_known = models.IntegerField(null=True, blank=True)
    num_crawled = models.IntegerField(null=True, blank=True)
    num_blocked = models.IntegerField(null=True, blank=True)
    blocked_to_crawled_ratio = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=7)
    # Don't make decisions based on this, it's not guaranteed.
    # But we should be able to call categorize_language and have it
    # scan all TLDs tagged with a particular language.
    default_language = models.CharField(max_length=8, null=True, blank=True)
    # This is the score adjustment for the domain suffix when indexing.
    score_adjustment = models.IntegerField(default=0)
    last_updated = models.DateTimeField(null=True, blank=True, auto_now=True)

    def __str__(self):
        return self.extension

    class Meta:
        in_db = 'indexes'
        ordering = ['extension', ]


def RandomValue():
    return random.randint(0, 2000000000)


class CrawlableUrl(models.Model):
    rooturl = models.CharField(max_length=260, db_index=True, null=False, blank=False)
    url = models.TextField(unique=True)
    randval = models.IntegerField(null=False, db_index=True, blank=True)

    def save(self, *args, **kwargs):
        # Sets a new random value every time the link is saved.
        self.randval = RandomValue()
        super(CrawlableUrl, self).save(*args, **kwargs)

    def __str__(self):
        return self.url

    class Meta:
        in_db = 'urls'


class SearchLogBase(models.Model):
    keywords = models.TextField(unique=False, db_index=True)
    result_count = models.IntegerField()
    last_search = models.DateTimeField(auto_now_add=True)
    search_time = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=6)
    # Are all terms in this search indexed?
    indexed = models.BooleanField(blank=True, default=False)
    referer = models.CharField(max_length=255, null=True, blank=True)
    ip = models.CharField(max_length=16, null=True, blank=True)
    ip_country = models.CharField(max_length=3, null=True, blank=True)
    browserstring = models.CharField(max_length=255, null=True, blank=True)
    is_bot = models.BooleanField(default=False, blank=True)
    search_id = models.UUIDField(null=True, default=uuid.uuid4, editable=False, db_index=True)

    class Meta:
        in_db = 'indexes'
        abstract = True


class SearchLog(SearchLogBase):

    def __str__(self):
        return self.keywords


class DomainSearchLog(SearchLogBase):
    # What language site was this domain searched from?
    language = models.CharField(max_length=6)

    def __str__(self):
        return self.keywords


class IPSearchLog(SearchLogBase):
    # What language site was this domain searched from?
    language = models.CharField(max_length=6)

    def __str__(self):
        return self.keywords


class PendingIndexBase(models.Model):
    keywords = models.CharField(max_length=240, unique=True)
    date_added = models.DateTimeField(auto_now_add=True)
    reason = models.CharField(max_length=240, blank=True, null=True)
    priority = models.IntegerField(choices=PRIORITY_CHOICES, blank=True, default=2, db_index=True)

    class Meta:
        in_db = 'indexes'
        abstract = True


class PendingIndex(PendingIndexBase):

    def __str__(self):
        return self.keywords

    class Meta:
        in_db = 'indexes'
        verbose_name_plural = "pending indexes"


class IndexTermBase(models.Model):
    keywords = models.CharField(max_length=240, unique=True)
    date_indexed = models.DateTimeField(default=timezone.now)
    page_rankings = models.TextField()
    num_results = models.IntegerField(null=True, blank=True, help_text='Number of results shown in search (max 200), or for multi-word, number of exact matches found in the db.')
    num_pages = models.IntegerField(null=True, blank=True, help_text='Number of pages found in the database (max 1000000).')
    index_time = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=8, help_text='in seconds')
    # Newer batteries-included JSON format for search results.
    search_results = models.TextField(null=True, blank=True)
    actively_blocked = models.BooleanField(default=False, blank=True)
    # Do we refuse to show any search results for this term?
    refused = models.BooleanField(default=False, blank=True)
    typo_for = models.CharField(max_length=240, null=True, blank=True, help_text='A phrase that this search term is a possible typo for.')
    is_language = models.CharField(max_length=4, null=True, blank=True, help_text='This is a word in language X, and will show a link to that index in search results.')
    term_weight = models.IntegerField(null=True, blank=True, help_text='Term weight in percent (for multi-word terms). If set below 100, this term will count less than other words.')

    def save(self, keep_date=False, *args, **kwargs):
        if not keep_date:
            self.date_indexed = timezone.now()
        super(IndexTermBase, self).save(*args, **kwargs)

    class Meta:
        in_db = 'indexes'
        abstract = True


class IndexTerm(IndexTermBase):
    show_ad = models.BooleanField(blank=True, default=False)
    verified_english = models.BooleanField(blank=True, default=False)

    def __str__(self):
        return self.keywords


class FeedbackItem(models.Model):
    keywords = models.CharField(max_length=240, null=True, blank=True)
    num_search_results = models.IntegerField(null=True, blank=True)
    comment = models.TextField()
    date_added = models.DateField(auto_now_add=True)
    processed = models.BooleanField(blank=True, default=False)
    ip = models.CharField(max_length=16, null=True, blank=True)
    language = models.CharField(max_length=8, null=True, blank=True)

    class Meta:
        in_db = 'indexes'

    def __str__(self):
        return 'Feedback on ' + self.keywords


class ChangelogItem(models.Model):
    title = models.CharField(max_length=240, null=True, blank=True)
    num_urls_crawled = models.IntegerField(null=True, blank=True)
    num_terms_indexed = models.IntegerField(null=True, blank=True)
    num_domains_blocked = models.IntegerField(null=True, blank=True)
    comment = models.TextField()
    date_added = models.DateField()
    version = models.TextField(null=True, blank=True)

    class Meta:
        in_db = 'indexes'

    def __str__(self):
        return str(self.date_added) + ': ' + self.comment


class Setting(models.Model):
    name = models.CharField(max_length=80)
    value = models.CharField(max_length=120)

    class Meta:
        in_db = 'indexes'

    def __str__(self):
        return self.name + ': ' + self.value


class SiteInfoFull(SiteInfo):
    class Meta:
        proxy = True
        verbose_name_plural = 'Site Infos - Full View'


# Model for holding a point-in-time snapshot of the index statistics.
class IndexStats(models.Model):
    num_excluded = models.IntegerField()
    # JSON data for the number of URLs crawled, terms indexed, and pending indexes.
    langs = models.TextField()
    total_urls = models.IntegerField()
    total_indexes = models.IntegerField()
    total_pendingindexes = models.IntegerField()
    create_date = models.DateTimeField(auto_now_add=True)
    most_linked_to_domains = models.TextField()
    last_most_linked_to = models.DateTimeField(null=True, blank=True)
    generation_time = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=8)

    def __str__(self):
        return 'Index Stats on ' + str(self.create_date)

    class Meta:
        in_db = 'indexes'
        ordering = ['-create_date', ]
        verbose_name_plural = 'Index Stats'


# Model for holding a monthly report of the most popular searches.
class MonthlySearchReport(models.Model):
    language = models.CharField(max_length=3)
    total_searches = models.IntegerField()
    total_result_clicks = models.IntegerField(null=True, blank=True)
    month = models.IntegerField()
    year = models.IntegerField()
    # JSON data for the search term and number of times found.
    top_searches = models.TextField()
    create_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.language + ' search report for ' + str(self.year) + '-' + str(self.month)

    class Meta:
        in_db = 'indexes'
        ordering = ['-year', '-month', 'language']


class PageLink(models.Model):
    rooturl_source = models.CharField(max_length=260, blank=True, null=False, db_index=True)
    url_source = models.CharField(max_length=2048, blank=True, null=False, db_index=True)
    url_destination = models.CharField(max_length=2048, blank=True, null=False)
    rooturl_destination = models.CharField(max_length=260, blank=True, null=False, db_index=True)
    anchor_text = models.CharField(max_length=255, null=True, blank=True)

    def __str__(self):
        return self.url_source + ' links to ' + self.url_destination

    class Meta:
        in_db = 'urls'


class KeywordRank(models.Model):
    keywords = models.CharField(max_length=240, unique=False, db_index=True)
    rank = models.IntegerField()
    rooturl = models.CharField(max_length=260, blank=True, null=False, db_index=True)
    show = models.BooleanField(default=True, blank=True)

    def __str__(self):
        return self.rooturl + ' ranks ' + str(self.rank) + ' for ' + self.keywords

    class Meta:
        in_db = 'indexes'
        abstract = True


class KeywordRanking(KeywordRank):
    pass


class QueryParameter(models.Model):
    """
    Represents a URL query parameter that should be changed or removed for a site.

    For example, to change affiliate codes on www.amazon.com, set the parameter to 'tag', the domain to 'www.amazon.com',
    the replace_with to 'zetacentauri-20', the remove_before_crawl to True, the remove_or_replace_after_crawl to True.

    To remove the session IDs for a site, set remove_before_crawl and remove_after_crawl both to True for a parameter.
    """
    parameter = models.CharField(max_length=60, unique=False)
    domain = models.CharField(max_length=260, blank=True, null=False, db_index=True)
    replace_with = models.CharField(max_length=100, blank=True, null=True, help_text='What should the parameter contents be replaced with? If blank, the tag will be removed.')
    # These two are separate so we can have a situation where a tag is removed before crawl and then replaced after crawl.
    remove_before_crawl = models.BooleanField(blank=True, default=False, help_text='Should this parameter be removed before crawling?')
    replace_before_crawl = models.BooleanField(blank=True, default=False, help_text='Should this parameter be replaced before crawling?')
    remove_or_replace_after_crawl = models.BooleanField(blank=True, default=True, help_text='Should this parameter be removed or replaced after crawling?')
    only_replace_if_present = models.BooleanField(blank=True, default=False, help_text='Only replace the URL parameter if it is already present.')

    def __str__(self):
        return 'Change parameter {0} for {1}'.format(self.parameter, self.domain)

    class Meta:
        in_db = 'urls'


class PageIFrame(models.Model):
    rooturl_source = models.CharField(max_length=260, blank=True, null=False, db_index=True)
    url_source = models.CharField(max_length=2048, blank=True, null=False, db_index=True)
    url_destination = models.CharField(max_length=2048, blank=True, null=False)
    rooturl_destination = models.CharField(max_length=260, blank=True, null=False)

    def __str__(self):
        return self.url_source + ' has an iframe to ' + self.url_destination

    class Meta:
        in_db = 'urls'


class PageJavaScript(models.Model):
    rooturl_source = models.CharField(max_length=260, blank=True, null=False, db_index=True)
    url_source = models.CharField(max_length=2048, blank=True, null=False, db_index=True)
    url_destination = models.CharField(max_length=2048, blank=True, null=False)
    rooturl_destination = models.CharField(max_length=260, blank=True, null=False)
    filename = models.CharField(max_length=255, null=True, blank=True)

    def __str__(self):
        return self.url_source + ' loads the JavaScript at ' + self.url_destination

    class Meta:
        in_db = 'urls'


class DMCANotice(models.Model):
    date = models.DateField()
    sender = models.CharField(max_length=240)
    url = models.CharField(max_length=240)
    contents = models.TextField()
    validity = models.TextField()
    action_taken = models.TextField()
    notes = models.TextField(null=True, blank=True)

    class Meta:
        in_db = 'indexes'


class NewsSite(models.Model):
    """
    Represents a news site meant to be included in news search.
    """
    url = models.CharField(max_length=260, blank=True, null=False, db_index=True)

    def __str__(self):
        return self.url

    class Meta:
        in_db = 'news'


class AutoCompleteBase(models.Model):
    keywords = models.TextField(unique=False, db_index=True)
    score = models.IntegerField()

    class Meta:
        in_db = 'indexes'
        ordering = ['-score', ]
        abstract = True


class AutoComplete(AutoCompleteBase):

    def __str__(self):
        return self.keywords


class ResultClickBase(models.Model):
    keywords = models.TextField(unique=False)
    search_id = models.UUIDField(null=True, editable=False, db_index=True)
    position = models.IntegerField()
    ip = models.CharField(max_length=16, blank=True, null=True, unique=False)
    url = models.TextField(blank=False, db_index=True)
    click_time = models.DateTimeField(auto_now_add=True)
    xpos = models.IntegerField(null=True, blank=True)
    ypos = models.IntegerField(null=True, blank=True)

    class Meta:
        in_db = 'indexes'
        abstract = True

    def __str__(self):
        return '{0} at position {1} in search {2}'.format(self.url, self.position, self.keywords)


class ResultClick(ResultClickBase):
    pass


class APIUser(models.Model):
    name = models.CharField(max_length=100)
    userid = models.IntegerField(null=True, blank=True)

    class Meta:
        in_db = 'indexes'


class APIToken(models.Model):
    user = models.ForeignKey(APIUser)
    key = models.CharField(max_length=64)

    class Meta:
        in_db = 'indexes'


class APISubscription(models.Model):
    user = models.ForeignKey(APIUser)
    monthly_calls = models.IntegerField(default=5000)
    expires = models.DateField()

    class Meta:
        in_db = 'indexes'


class APIUsage(models.Model):
    user = models.ForeignKey(APIUser)
    month = models.IntegerField()
    year = models.IntegerField()
    calls_used = models.IntegerField(default=0)

    class Meta:
        in_db = 'indexes'


# Incvidual language class definitions. Presence or absence of the language code in language_list enables or disables these.
if 'af' in language_list:
    class SiteInfo_af(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_af(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_af(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_af(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_af(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_af(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_af(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

if 'an' in language_list:
    class SiteInfo_an(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_an(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_an(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_an(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_an(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_an(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_an(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'bs' in language_list:
    class SiteInfo_bs(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_bs(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_bs(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_bs(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_bs(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_bs(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_bs(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'ca' in language_list:
    class SiteInfo_ca(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_ca(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_ca(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_ca(KeywordRank):
        pass

        class Meta:
            in_db = 'language_indexes'

    class SearchLog_ca(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_ca(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_ca(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'cs' in language_list:
    class SiteInfo_cs(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_cs(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_cs(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_cs(KeywordRank):
        pass

        class Meta:
            in_db = 'language_indexes'

    class SearchLog_cs(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_cs(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_cs(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'cy' in language_list:
    class SiteInfo_cy(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_cy(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_cy(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_cy(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_cy(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_cy(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_cy(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'da' in language_list:
    class SiteInfo_da(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_da(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_da(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_da(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_da(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_da(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_da(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'de' in language_list:
    class SiteInfo_de(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_de(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_de(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_de(KeywordRank):
        pass

        class Meta:
            in_db = 'language_indexes'

    class SearchLog_de(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_de(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_de(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'el' in language_list:
    class SiteInfo_el(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_el(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_el(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_el(KeywordRank):
        pass

        class Meta:
            in_db = 'language_indexes'

    class SearchLog_el(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_el(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_el(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'eo' in language_list:
    class SiteInfo_eo(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_eo(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_eo(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_eo(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_eo(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_eo(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_eo(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'es' in language_list:
    class SiteInfo_es(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_es(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_es(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_es(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_es(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_es(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_es(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'et' in language_list:
    class SiteInfo_et(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_et(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_et(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_et(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_et(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_et(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_et(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'eu' in language_list:
    class SiteInfo_eu(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_eu(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_eu(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_eu(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_eu(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_eu(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_eu(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'fi' in language_list:
    class SiteInfo_fi(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_fi(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_fi(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_fi(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_fi(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_fi(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_fi(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'fo' in language_list:
    class SiteInfo_fo(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_fo(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_fo(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_fo(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_fo(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_fo(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_fo(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'fr' in language_list:
    class SiteInfo_fr(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_fr(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_fr(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_fr(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_fr(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_fr(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_fr(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'ga' in language_list:
    class SiteInfo_ga(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_ga(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_ga(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_ga(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_ga(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_ga(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_ga(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'gl' in language_list:
    class SiteInfo_gl(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_gl(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_gl(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_gl(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_gl(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_gl(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_gl(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'ha' in language_list:
    class SiteInfo_ha(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_ha(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_ha(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_ha(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_ha(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_ha(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_ha(AutoCompleteBase):
        def __str__(self):
            return self.keywords


if 'hr' in language_list:
    class SiteInfo_hr(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_hr(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_hr(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_hr(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_hr(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_hr(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_hr(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'hu' in language_list:
    class SiteInfo_hu(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_hu(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_hu(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_hu(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_hu(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_hu(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_hu(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'is' in language_list:
    class SiteInfo_is(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_is(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_is(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_is(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_is(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_is(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_is(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'it' in language_list:
    class SiteInfo_it(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_it(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_it(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_it(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_it(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_it(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_it(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'la' in language_list:
    class SiteInfo_la(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_la(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_la(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_la(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_la(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_la(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_la(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'lb' in language_list:
    class SiteInfo_lb(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_lb(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_lb(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_lb(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_lb(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_lb(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_lb(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'lt' in language_list:
    class SiteInfo_lt(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_lt(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_lt(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_lt(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_lt(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_lt(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_lt(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'lv' in language_list:
    class SiteInfo_lv(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_lv(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_lv(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_lv(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_lv(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_lv(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_lv(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'mg' in language_list:
    class SiteInfo_mg(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_mg(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_mg(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_mg(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_mg(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_mg(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_mg(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'mt' in language_list:
    class SiteInfo_mt(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_mt(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_mt(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_mt(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_mt(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_mt(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_mt(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'nl' in language_list:
    class SiteInfo_nl(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_nl(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_nl(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_nl(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_nl(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_nl(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_nl(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'no' in language_list:
    class SiteInfo_no(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_no(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_no(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_no(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_no(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_no(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_no(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'oc' in language_list:
    class SiteInfo_oc(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_oc(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_oc(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_oc(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_oc(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_oc(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_oc(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'pl' in language_list:
    class SiteInfo_pl(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_pl(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_pl(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_pl(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_pl(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_pl(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_pl(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'pt' in language_list:
    class SiteInfo_pt(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_pt(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_pt(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_pt(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_pt(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_pt(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_pt(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'qu' in language_list:
    class SiteInfo_qu(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_qu(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_qu(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_qu(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_qu(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_qu(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_qu(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'ro' in language_list:
    class SiteInfo_ro(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_ro(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_ro(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_ro(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_ro(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_ro(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_ro(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'rw' in language_list:
    class SiteInfo_rw(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_rw(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_rw(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_rw(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_rw(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_rw(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_rw(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'sk' in language_list:
    class SiteInfo_sk(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_sk(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_sk(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_sk(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_sk(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_sk(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_sk(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'sl' in language_list:
    class SiteInfo_sl(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_sl(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_sl(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_sl(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_sl(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_sl(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_sl(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'sn' in language_list:
    class SiteInfo_sn(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_sn(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_sn(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_sn(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_sn(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_sn(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_sn(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'so' in language_list:
    class SiteInfo_so(URLInfo):

        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_so(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_so(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_so(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_so(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_so(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_so(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'sv' in language_list:
    class SiteInfo_sv(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_sv(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_sv(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_sv(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_sv(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_sv(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_sv(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'sw' in language_list:
    class SiteInfo_sw(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_sw(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_sw(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_sw(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_sw(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_sw(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_sw(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'tr' in language_list:
    class SiteInfo_tr(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_tr(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_tr(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_tr(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_tr(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_tr(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_tr(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'vo' in language_list:
    class SiteInfo_vo(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_vo(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_vo(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_vo(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_vo(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_vo(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_vo(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'wa' in language_list:
    class SiteInfo_wa(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_wa(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_wa(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_wa(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_wa(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_wa(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_wa(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'wo' in language_list:
    class SiteInfo_wo(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_wo(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_wo(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_wo(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_wo(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_wo(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_wo(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'xh' in language_list:
    class SiteInfo_xh(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_xh(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_xh(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_xh(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_xh(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_xh(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_xh(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'yo' in language_list:
    class SiteInfo_yo(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_yo(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_yo(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_yo(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_yo(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_yo(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_yo(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


if 'zu' in language_list:
    class SiteInfo_zu(URLInfo):
        def __str__(self):
            return self.url

        class Meta:
            in_db = 'language_pages'

    class PendingIndex_zu(PendingIndexBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class IndexTerm_zu(IndexTermBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class KeywordRanking_zu(KeywordRank):
        class Meta:
            in_db = 'language_indexes'

    class SearchLog_zu(SearchLogBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'

    class ResultClick_zu(ResultClickBase):
        class Meta:
            in_db = 'language_indexes'

    class AutoComplete_zu(AutoCompleteBase):
        def __str__(self):
            return self.keywords

        class Meta:
            in_db = 'language_indexes'


class FileDownload(models.Model):
    filename = models.CharField(max_length=80, null=False, blank=False)
    count = models.IntegerField(null=False, blank=False)
    version = models.DecimalField(decimal_places=4, max_digits=8, null=False, blank=False)
    enabled = models.BooleanField(default=True)
    notes = models.TextField(blank=True, null=True)
    date_added = models.DateField(auto_now_add=True)

    def __str__(self):
        return self.filename

    class Meta:
        in_db = 'indexes'
