import datetime from urllib import parse from django.contrib.auth.models import User from django.contrib.gis.db import models from django.db import connection from django.template.defaultfilters import slugify from django.utils.translation import ugettext_lazy as _ from django_extensions.db.fields import AutoSlugField from django_countries.fields import CountryField from multiselectfield import MultiSelectField from phonenumber_field.modelfields import PhoneNumberField from . import validators class CaseStudyDraft(models.Model): author = models.ForeignKey( User, on_delete=models.CASCADE ) created = models.DateTimeField(auto_now_add=True) data = models.TextField() def __str__(self): return "{0.author.username}, {0.created:%Y-%m-%d %H:%M}".format(self) class SpatialRefSys(connection.ops.spatial_ref_sys()): def __str__(self): return self.__unicode__() def __unicode__(self): return '{0.auth_name}:{0.auth_srid} {0.name}'.format(self) class Meta: proxy = True verbose_name = "spatial reference system" class CaseStudyQuerySet(models.QuerySet): def approved(self): return self.filter( approved=True ) class CaseStudy(models.Model): """Model for case studies submitted to the Ojuso Platform""" approved = models.BooleanField(default=False) # Choice lists for drop-downs POSITIVE_NEGATIVE_CHOICES = ( ('P', _('There is/was an organising process in favour of the project')), ('N', _('There is/was an organising process against the project')), ('X', _('There is/was no organising process')), ('U', _('Unsure/unknown')) ) LAND_OWNERSHIP_CHOICES = ( ('PRI', _('Private land')), ('PUB', _('Public/state land')), ('COM', _('Community/communal/customary land')), ('CON', _('Contested/in conflict')), ('OTH', _('Other')), ) LOCATION_CONTEXT_CHOICES = ( ('RUR', _('Rural')), ('URB', _('Urban')), ('MIX', _('Mixed')), ) TYPE_OF_ECOSYSTEM_CHOICES = ( ('MARINE', _('Marine (e.g. ocean, sea)')), ('FRESH', _('Freshwater (e.g. river, lake)')), ('FOREST', _('Forest/jungle')), ('AGRI', _('Agricultural land')), ('GRASS', _('Grassland')), ('DESERT', _('Desert (tundra, ice or sand)')), ('WETLND', _('Wetland (marsh, mangrove, peat Soil)')), ('URBAN', _('Urban')) ) AFFECTED_COMMUNITIES_CHOICES = ( ('INDIG', _('Indigenous people(s)')), ('AFRO', _('Afro-descendants')), ('MIG', _('Migrants')), ('REF', _('Refugees')), ('OTHER', _('Other communities or identities')), ) PROJECT_STATUS_CHOICES = ( ('INIT', _('Initial/conceptual')), ('PROJCD', _('In planning and design')), ('FAIL', _('Failed')), ('UCONST', _('Under construction')), ('EXSTNG', _('In operation')), ('DECOMM', _('Undergoing decommissioning')), ('END', _('Decommissioned')), ) FINANCIAL_INSTITUTIONS = ( ('AfDB', _('African Development Bank (AfDB)')), ('BADEA', _('Arab Bank for Economic Development in Africa (BADEA)')), ('ADB', _('Asian Development Bank (ADB)')), ('AIIB', _('Asian Infrastructure Investment Bank (AIIB)')), ('BSTDB', _('Black Sea Trade and Development Bank (BSTDB)')), ('CAF', _('Corporacion Andina de Fomento / Development Bank of Latin America (CAF)')), ('CDB', _('Caribbean Development Bank (CDB)')), ('CABEI', _('Central American Bank for Economic Integration (CABEI)')), ('EADB', _('East African Development Bank (EADB)')), ('ETDB', _('Economic Cooperation Organization Trade and Development Bank (ETDB)')), ('EDB', _('Eurasian Development Bank (EDB)')), ('EBRD', _('European Bank for Reconstruction and Development (EBRD)')), ('EC', _('European Commission (EC)')), ('EIB', _('European Investment Bank (EIB)')), ('IADB', _('Inter-American Development Bank Group (IDB, IADB)')), ('IFAD', _('International Fund for Agricultural Development (IFAD)')), ('IIB', _('International Investment Bank (IIB)')), ('IsDB', _('Islamic Development Bank (IsDB)')), ('FMO', _('Nederlandse Financieringsmaatschappij voor Ontwikkelingslanden NV (Netherlands Development Finance Company, FMO)')), ('NDB', _('New Development Bank (NDB) (formerly BRICS Development Bank)')), ('NDF', _('The Nordic Development Fund')), ('NIB', _('Nordic Investment Bank (NIB)')), ('OFID', _('OPEC Fund for International Development (OFID)')), ('BOAD', _('West African Development Bank (BOAD)')), ('WB', _('World Bank')), ) SECTOR_CHOICES = ( ('RN', _('Renewable energy generation project')), ('PG', _('Energy networks')), ('ST', _('Energy storage facilities')), ('SM', _('Mining related to the renewable energy economy')), ('MA', _('Manufacturing and/or processing of equipment')) ) GENERATION_TYPE_CHOICES = ( ('POW', _('Electricity')), ('HOT', _('Heat/Cold')), ('CHP', _('Combined Heat/Cold and Power (CHP, CCP or CCHP)')), ) GENERATION_TECHNOLOGY_CHOICES = ( ('BIO', _('Bio-energy')), ('GEOT', _('Geothermal electricity')), (_('Hydro'), ( ('uHYD', _('Micro hydro (<100kW)')), ('SHYD', _('Small-scale hydro (100kW-1MW)')), ('MHYD', _('Medium-scale hydro (1-30MW)')), ('LHYD', _('Large-scale hydro (>30MW - often not considered renewable)')), )), (_('Marine'), ( ('WAVE', _('Wave')), ('TSTR', _('Tidal stream')), ('TBAR', _('Tidal barrage/lagoon')), ('TOTH', _('Other')), )), (_('Solar'), ( ('SSPV', _('Small-scale photovoltaic (<500kW)')), ('LSPV', _('Large-scale photovoltaic (>500kW)')), ( 'CSP', _('Solar power tower')), ('PARA', _('Parabolic trough (open or enclosed)')), ('FRES', _('Fresnel reflector')), ('STIR', _('Dish Stirling')), )), (_('Wind'), ( ('SSWE', _('Small-scale wind (<500kW)')), ('LSWE', _('Large-scale wind (>500kW)')) )), ('OTHR', _('Other')) ) POWER_TECHNOLOGY_CHOICES = ( ('PT', _('Electrical power transmission/distribution')), ('HN', _('Heat networks')), ('OT', _('Other')), ) TYPE_OF_EXTRACTION_CHOICES = ( ('SUR', _('Surface (open pit/open cast/open cut mining)')), ('SUB', _('Sub-surface (underground mining)')), ('SEA', _('Seabed mining')), ('URB', _('Urban mining/recycling')) ) MINERAL_COMMODITY_CHOICES = ( ('ALU', _('Aluminium (Bauxite)')), ('ARS', _('Arsenic')), ('BER', _('Beryllium')), ('CAD', _('Cadmium')), ('CHR', _('Chromium')), ('COK', _('Coking coal (for steel)')), ('COP', _('Copper')), ('GAL', _('Gallium')), ('GER', _('Germanium')), ('GLD', _('Gold')), ('HRE', _( 'Heavy rare earth elements (gadolinium, terbium, dysprosium, holmium,' ' erbium, thulium, ytterbium, lutetium, yttrium, scandium)')), ('IRN', _('Iron')), ('LRE', _( 'Light rare earth elements (lanthanum, cerium, praseodymium, neodymium,' ' promethium, samarium, europium)')), ('LED', _('Lead')), ('LIT', _('Lithium')), ('MAN', _('Manganese')), ('MER', _('Mercury')), ('MOL', _('Molybdenum')), ('NIC', _('Nickel')), ('NIO', _('Niobium')), ('PGM', _( 'Platinum group metals (ruthenium, rhodium, palladium, osmium,' ' iridium, and platinum)')), ('RHE', _('Rhenium')), ('SIL', _('Silicon')), ('SIV', _('Silver')), ('TAN', _('Tantalum')), ('TEL', _('Tellurium')), ('THA', _('Thallium')), ('TIN', _('Tin')), ('TIT', _('Titanium')), ('TUN', _('Tungsten')), ('VAN', _('Vanadium')), ('ZNC', _('Zinc')), ('OTR', _('Other')) ) USE_IN_ENERGY_ECONOMY_CHOICES = ( ('CPV', _('Concentrated solar power (CSP) tower')), ('EPT', _('Electrical power transmission/distribution infrastructure')), ('ESS', _('Energy storage')), ('GGM', _('Geothermal')), ('HGM', _('Hydropower')), ('HNT', _('Heat networks')), ('SPM', _('Solar photovoltaic')), ('STM', _('Solar thermal systems')), ('WTM', _('Wind power')), ('ESS', _("Don't know")), ('OTR', _('Other')) ) MANUFACTURING_TYPE_CHOICES = ( ('GENERATE', _('Manufacturing of renewable energy generation equipment')), ('TRANSSTORE', _('Manufacturing of energy transmission or storage equipment')), ('RECYCLE', _('Recycling/reusing equipment or raw materials')), ('DISPOSAL', _('Disposal of equipment')), ('OTHER', _('Other')), ) MANUFACTURING_RELATED_CHOICES = ( ('PV', _('Solar PV')), ('CSP', _('Concentrated solar power (CSP)')), ('WIND', _('Wind power')), ('HYDRO', _('Hydropower')), ('GEO', _('Geothermal')), ('TRANSMIT', _('Electrical power transmission infrastructure')), ('STORE', _('Energy storage')), ('HEAT', _('Heat networks')), ('OTHER', _('Other')), ('IDK', _('Unknown')), ) MANUFACTURING_FACTORS_CHOICES = ( ('LAND', _('Land use')), ('LABOR', _('Labor rights')), ('ENVIRO', _('Environmental factors')), ('LIFECYCLE', _('Lifecycle management')), ('OWN', _('Ownership')), ('OTHER', _('Other(s)')), ) POSITIVE_CASE_TYPE_CHOICES = ( ('CREP', _('Community project (co-)owned by individuals')), ('EACP', _( 'Community project owned by not-for-profit organizations and/or serving' ' the public interest')), ('PSEP', _('Public/state (federal, state, municipal) project')), ('CORS', _('Circular economy project / Reuse / Recycling')), ) NEGATIVE_CASE_REASONS_CHOICES = ( ('VOLR', _('Violation of land rights')), ('VOHR', _( 'Violation of fundamental human rights, indigenous rights and/or other' ' collective rights')), ('EIMP', _( 'Environmental impacts (severe impacts on ecosystems / violation of laws' ' plans or programs of environmental conservation, etc.')), ('NCUL', _( 'Negative cultural impacts (erosion/destruction of bio-cultural heritage,' ' impacts on sacred land, etc.)')), ('AGGR', _( 'Aggression/threats to community members opposed to the project,' ' collaboration with organized crime, etc.')), ('ALAB', _('Abusive labour practices')), ('CRUP', _( 'Corruption and/or irregular permitting or contracting, conflicts of' ' interest, etc.')), ) # Dynamically generate a list of choices 40 years prior and after the current year. YEAR_CHOICES = [(r, r) for r in range((datetime.datetime.now().year - 40), (datetime.datetime.now().year + 41))] ## # Meta Fields ## # User who submitted case study author = models.ForeignKey( User, on_delete=models.SET_NULL, blank=True, null=True, editable=False ) # Date and time of submission date_created = models.DateTimeField(auto_now_add=True, null=False) # Slug derived from entry_name, used in urls for SEO slug = AutoSlugField(populate_from=['entry_name'], editable=False) # Language this case study is written in language = models.CharField(max_length=16, blank=True) # Long or short case study? form_type = models.CharField(max_length=16, blank=True) ## # Territory info ## location = models.PointField( verbose_name=_("Project location") ) shapefiles_label = _( "Do you have geographic information files about the territory impacted by" " this project?" ) shapefiles_help_text = _( "For example, of the limits of the land within which a project is taking" " place, or of sites of particular importance. You can upload data in" " different formats (ESRI Shapefiles with file extensions like .cpg, .dbf," " .prj, .qpj, .shp, .shx., or GeoPackage gpkg, GeoJSON, KML, GML, etc.)." " Write to database@ojuso.org if you need help." ) shapefiles = models.ManyToManyField( 'files.File', related_name='shapefile_for', verbose_name=shapefiles_label, help_text=shapefiles_help_text, blank=True ) coordinate_reference_system = models.ForeignKey( SpatialRefSys, null=True, blank=True, default=4326, on_delete=models.PROTECT ) name_of_territory_or_area = models.CharField( verbose_name=_("Name of territory or area"), max_length=512, blank=True ) ## # First Screen - Basic information ## # 1.1 entry_name = models.CharField( verbose_name=_("Project name"), help_text=_("Please write the local name, followed by any translated name if necessary."), max_length=128 ) # 1.4 country = CountryField( verbose_name=_("Country"), help_text=_("Please select the country of the project.") ) # 1.5.1 area_of_land = models.IntegerField( verbose_name=_("Approximate land area"), help_text=_("The area of land covered by the project (km²)") ) # 1.5.2 land_ownership = models.CharField( verbose_name=_("Land ownership/tenure"), help_text=_("What type of ownership/tenure does the land fall under?"), max_length=3, choices=LAND_OWNERSHIP_CHOICES ) # 1.5.3 land_ownership_details = models.TextField( verbose_name=_("Land ownership/tenure details"), help_text=_("
Please specify details about land ownership," " including conflicting claims, unrecognized customary rights, " " conflicts around land lease or purchase contracts, etc." "" "
We understand this is a difficult question, so" " please try to provide just the information you know.
"), max_length=256, blank=True, ) # 1.5.4 location_context = models.CharField( verbose_name=_("Location"), help_text=_( "Please select the context that is most applicable to this case study."), max_length=3, choices=LOCATION_CONTEXT_CHOICES ) # 1.5.5 type_of_ecosystem = MultiSelectField( verbose_name=_("Type(s) of ecosystem"), max_length=56, choices=TYPE_OF_ECOSYSTEM_CHOICES, blank=True ) # 1.5.5.3 describe_ecosystem = models.TextField( verbose_name=_("Please describe the ecosystem."), ) affected_communities = MultiSelectField( verbose_name=_("Communities or identities present in the project area"), max_length=50, choices=AFFECTED_COMMUNITIES_CHOICES, blank=True ) people_affected_other = models.TextField( verbose_name=_("Communities or identities – further detail"), help_text=_("Please describe further the communities or identities present in the project area."), blank=True ) # 1.6 project_status = models.CharField( verbose_name=_("Status of project"), max_length=6, choices=PROJECT_STATUS_CHOICES ) # 1.7 start_year = models.IntegerField( verbose_name=_("Construction start year"), help_text=_("Please select the year project construction began." "If the project is not yet in construction, select the assumed" " start year as detailed in company information or media."), choices=YEAR_CHOICES, blank=True, null=True ) # 1.8 completion_year = models.IntegerField( verbose_name=_("Operation start year"), help_text=_( "Please select the year the project's operation and maintenance (O&M) phase" " began. If the project is not yet in operation, select the year operation " " is expected to begin as detailed in company information or media."), choices=YEAR_CHOICES, default=None, null=True, blank=True ) # 1.9 synopsis = models.TextField( verbose_name=_("Project synopsis"), help_text=_("Please briefly summarise the project. (Maximum 500 characters.)"), max_length=500 ) # 1.10 full_description = models.TextField( verbose_name=_("Full description"), help_text=_("Please describe the project in full. Separate paragraphs with two" " new lines. Please add as much detail as you feel is necessary" " here.") ) # 1.11 project_owners = models.TextField( verbose_name=_("Project owners"), help_text=_("Please list companies or organisations that own the project." " Write each name in a new line."), blank=True ) consultants_contractors = models.TextField( verbose_name=_("Consultants and contractors"), help_text=_("Please list consultants, planners or organisations that are doing" " the planning, construction, operation or maintenance work relating" " to the project and/or facilities. Separate each with a new line."), blank=True ) # 1.12 shareholders = models.TextField( verbose_name=_("Shareholders of the project owners"), help_text=_("List the shareholders of the company/companies that own the" " project, if you have this information. Separate with a new line."), blank=True ) # 1.13.1 financial_institutions = MultiSelectField( verbose_name=_("Financial institutions"), help_text=_("Please select any financial institutions (public or private) that" " have, or are considering extending loans or guarantees to the" " project."), choices=FINANCIAL_INSTITUTIONS, blank=True ) # 1.13.2 financial_institutions_other = models.TextField( verbose_name=_("Financial institutions – other"), help_text=_("Please list any other financial institutions not listed above." " Separate with a new line."), blank=True ) # 1.15.1, 1.15.2, 1.15.3 images = models.ManyToManyField( 'files.ImageFile', related_name='image_for', verbose_name=_("Images"), blank=True ) # 1.16.1 video = models.URLField( verbose_name=_("Video URL"), help_text=_("Copy the URL to a YouTube or Vimeo video that relates to the case study."), max_length=80, validators=[validators.YouTubeOrVimeoValidator()], blank=True ) # 1.16.2 video_caption = models.CharField( verbose_name=_("Video caption"), max_length=240, blank=True, ) # 1.16.3 video_credit = models.CharField( verbose_name=_("Video credit(s)"), max_length=240, blank=True, ) # 1.17.1 media_coverage_mainstream = models.TextField( verbose_name=_("Links to media reports"), help_text=_("Please provide any links to mainstream media coverage."), blank=True, ) # 1.17.2 media_coverage_independent = models.TextField( verbose_name=_("Independent grassroots reports"), help_text=_("Please provide any links to grassroots/independent media coverage."), blank=True, ) # 1.18.1 community_voices = models.TextField( verbose_name=_("Community Voices"), help_text=_( "Please add any direct quotes from members of the community that relate" " to this project."), blank=True, ) # 1.18.2 direct_comms = models.TextField( verbose_name=_("Reports of direct communications"), help_text=_( "Please add any reports of direct communication between community members" " and representatives of developers/companies/investors. If you have files" " to upload, you can do this in 'other documents' on the 'uploads' tab."), blank=True, ) # 1.18.3 social_media_links = models.TextField( verbose_name=_("Social media links"), help_text=_( "Please add any links to social media accounts directly relating" " to the project."), max_length=500, blank=True, ) ## # Second Screen - Technical and economic analysis ## sector_of_economy = models.CharField( verbose_name=_("Sector of renewable energy economy"), max_length=3, choices=SECTOR_CHOICES ) energy_details = models.CharField( verbose_name=_("Technology type"), help_text=_("Please provide more information about the type of technology this case study focuses on."), max_length=200, blank=True ) ## Energy generation project generation_type = models.CharField( verbose_name=_('What kind of energy is generated?'), max_length=4, choices=GENERATION_TYPE_CHOICES, blank=True ) generation_technology = models.CharField( verbose_name=_("Generation technology"), help_text=_("Please select the type of renewable energy generation that most" " applies to this case study."), max_length=4, choices=GENERATION_TECHNOLOGY_CHOICES, blank=True ) # Should be filled in if generation_technology was answered as bio-energy biomass_detail = models.CharField( verbose_name=_("Bio-energy feedstock"), help_text=_("Please describe the source of the fuel and how it is processed/used." " Please consider:
\n" "We do not expect users to know this information, but if you do " " it may be useful to give a fuller picture.
" "