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 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. freshwater, 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', _('Initiation/ideation')), ('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)')), ('IFFIm', _('International Finance Facility for Immunisation (IFFIm)')), ('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', _('Power')), ('HOT', _('Heat/Cool')), ('CHP', _('Combined Heat/Cool and Power (CHP)')), ) GENERATION_TECHNOLOGY_CHOICES = ( ('BIO', _('Bio-energy')), ('GEOT', _('Geothermal electricity')), (_('Hydro'), ( ('uHYD', _('Micro hydro (<100kW)')), ('SHYD', _('Small-scale hydro (<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', _('Concentrated solar power (CSP)')), ('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 (tidal, wave, etc.)')) ) POWER_TECHNOLOGY_CHOICES = ( ('PT', _('Electrical power transmission')), ('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')), ('COA', _('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)')), ('EPT', _('Electrical power transmission infrastructure')), ('ESS', _('Energy storage')), ('GGM', _('Geothermal')), ('HGM', _('Hydropower')), ('HNT', _('Heat networks')), ('SPM', _('Solar PV')), ('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', _('Reuse / recycling / circular economy project')), ) 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 or territorial governance systems,' ' 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 = models.ManyToManyField( 'files.File', related_name='shapefile_for', verbose_name=_("Geographic data"), help_text=_("If you have territory that you would like to show in relation to this project i.e. area(s) of land or water affected by the project, or maybe the limits of the land within which a project is taking place or the sites of particular objects of importance. ESRI Shapefiles are a popular file type: they comprise a set of 3 or more (often 5-6) files with file extensions like .cpg, .dbf, .prj, .qpj, .shp, .shx. Hold down Control, or Command on a Mac, to select more than one. You may have data as GeoPackage (gpkg), GeoJSON, KML, GML, etc. or have data in PostGIS or another spatial database management system already. Let us know (database@ojuso.org) if you have other file types or need help and we can work out how to import it."), 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=_("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=_("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=_("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=_("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=_("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=_("Briefly summarise the project. This will be displayed at the top of the case study page. (Maximum 500 chars)") ) # 1.10 full_description = models.TextField( verbose_name=_("Full description"), help_text=_("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 and facility owners"), help_text=_("List companies or organisations that own the project and/or facilities. \ Provide company numbers etc. if available. Separate with a new line."), blank=True ) consultants_contractors = models.TextField( verbose_name=_("Consultants and contractors"), help_text=_("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 shareholders of the project owners you've just listed. Separate with a new line."), blank=True ) # 1.13.1 financial_institutions = MultiSelectField( verbose_name=_("Financial institutions"), help_text=_("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=_("List any other financial institutions not listed above. \ Put each on 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=_("Provide any links to mainstream media coverage."), blank=True, ) # 1.17.2 media_coverage_independent = models.TextField( verbose_name=_("Independent grassroots reports"), help_text=_("Provide any links to grassroots/independent media coverage."), blank=True, ) # 1.18.1 community_voices = models.TextField( verbose_name=_("Community Voices"), help_text=_("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=_("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=_("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 economy"), max_length=3, choices=SECTOR_CHOICES ) energy_details = models.CharField( verbose_name=_("Further details"), help_text=_("Please give more information about the transmission, network or storage technology."), max_length=200, blank=True ) ## Energy generation project generation_type = models.CharField( verbose_name=_('What is being generated?'), max_length=4, choices=GENERATION_TYPE_CHOICES, blank=True ) generation_technology = models.CharField( verbose_name=_("Generation technology"), help_text=_("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:\
We do not expect users to know this information, but if you do \ it may be useful to give a fuller picture.\