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_countries.fields import CountryField from django_extensions.db.fields import AutoSlugField 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/distribution 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" "\n" "

We do not expect users to know this information, but if you do " " it may be useful to give a fuller picture.

" "
" ), max_length=200, blank=True, ) # 1.14 energy_customers = models.TextField( verbose_name=_("Energy service consumers/off-takers"), help_text=_( "Please list the customers that buy energy from the project, e.g. the" " national grid provider, or private companies. Also mention whether" " credits are being sold in the carbon markets. Separate with a new line." ), blank=True, ) # 2.1.2 total_generation_capacity = models.PositiveIntegerField( verbose_name=_("Total generation capacity (kW)"), blank=True, null=True ) # 2.1.4 total_investment = models.IntegerField( verbose_name=_("Total investment (in USD)"), help_text=_( "Please enter the approximate total investment for the project in" " United State Dollars (USD)." ), blank=True, null=True, ) # 2.2 - Power Grids / Energy Storage # 2.2.1 power_technology = models.CharField( verbose_name=_("Power technology"), max_length=2, choices=POWER_TECHNOLOGY_CHOICES, blank=True, ) # 2.2.1.4 power_technology_other = models.CharField( verbose_name=_("Further information about power technology"), max_length=128, blank=True, ) energy_storage_capacity = models.DecimalField( verbose_name=_("Total storage capacity (kWh)"), max_digits=20, decimal_places=3, blank=True, null=True, ) energy_transmission_capacity = models.DecimalField( verbose_name=_("Total transmission or distribution capacity (kW)"), max_digits=20, decimal_places=3, blank=True, null=True, ) # TODO: Auto-completion based on previous entries so we can query case-studies with the same answer. contractor_or_supplier_of_technology = models.TextField( verbose_name=_("Supplier of technology"), help_text=_( "Please list companies that supply the energy generation equipment" " - e.g. Siemens Gamesa, GE, Alstom, Vestas, Hanwha Q CELLS," " Mitsubishi, First Solar, Jinko Solar, Trina Solar," " Suzlon Energy, Statkraft, Shanghai Electric," " Ballard Power Systems, Panasonic, etc." ), blank=True, ) # 2.2.5 additional_technical_details = models.TextField( verbose_name=_("Additional technical or economic details"), help_text=_( "Please add any additional details that may help to explain the technical" " and economic aspects of this case study." ), blank=True, ) ## # Mining ## minerals_or_commodities = models.CharField( verbose_name=_("Primary mineral mined"), help_text=_("What mineral commodity is primarily mined here?"), max_length=3, choices=MINERAL_COMMODITY_CHOICES, blank=True, ) minerals_or_commodities_other = models.TextField( verbose_name=_("Other mineral commodities"), help_text=_( "Please enter any mineral commodities not in the list." " Separate each with a new line." ), blank=True, ) use_in_energy_economy = MultiSelectField( verbose_name=_("Potential use in renewable energy economy"), max_length=128, choices=USE_IN_ENERGY_ECONOMY_CHOICES, blank=True, ) use_in_energy_economy_other = models.CharField( verbose_name=_("Other"), max_length=128, blank=True ) project_life_span = models.CharField( verbose_name=_("Project life span"), help_text=_("e.g. 12 years of production, 15 years overall"), max_length=200, blank=True, ) size_of_concessions = models.CharField( verbose_name=_("Size of concessions (land/marine area)"), help_text=_( "Please describe the size of concession(s) granted to company/companies" " (e.g. 'one concession of 2,300 hectares (23km²)')" ), max_length=200, blank=True, ) projected_production_of_commodities = models.CharField( verbose_name=_("Estimated production of key commodities"), help_text=_( "Please describe the projected production of commodities per annum and" " overall.
\n" 'For example, "40 million tonnes of iron ore per year",' ' "200 million tonnes over 5 year life of mine"."' ), max_length=256, blank=True, ) type_of_extraction = models.CharField( verbose_name=_("Type of extraction"), max_length=3, choices=TYPE_OF_EXTRACTION_CHOICES, blank=True, ) associated_infrastructure = models.CharField( verbose_name=_("Associated infrastructure in the locality"), help_text=_( "Please list any associated infrastructure in the locality" " (e.g. tailings dams / mine waste storage and treatment facilities;" " ore processing facilities; smelting facilities;" " hydroelectric dams / energy infrastructure;" " transport infrastructure e.g. roads or rail)." ), max_length=256, blank=True, ) # -- Manufacturing -- manufacturing_type = models.CharField( verbose_name=_("Which of the following options best describes this case?"), max_length=16, choices=MANUFACTURING_TYPE_CHOICES, blank=True, ) manufacturing_description = models.TextField( verbose_name=_("Description"), help_text=_( "Please briefly describe manufacturing process and components/outputs." " (less than 500 characters)." ), max_length=500, blank=True, ) manufacturing_related_tech = MultiSelectField( verbose_name=_("What technology is this case related to?"), max_length=128, choices=MANUFACTURING_RELATED_CHOICES, blank=True, ) manufacturing_factors = MultiSelectField( verbose_name=_( "Please choose the factors that make this case remarkable, " "in a positive or negative way." ), max_length=128, choices=MANUFACTURING_FACTORS_CHOICES, blank=True, ) manufacturing_factors_description = models.TextField( verbose_name=_("Please describe these factors."), blank=True ) manufacturing_ownership = models.TextField( verbose_name=_( "Describe the ownership structure of the project and its relation with the local community." ), blank=True, ) ## # Socio-economic analysis ## positive_or_negative = models.CharField( verbose_name=_( "What is the relationship of local community organization(s) to this project?" ), max_length=1, choices=POSITIVE_NEGATIVE_CHOICES, ) positive_case_type = MultiSelectField( verbose_name=_("What kind of case is this entry about?"), choices=POSITIVE_CASE_TYPE_CHOICES, max_length=32, blank=True, ) negative_case_reasons = MultiSelectField( verbose_name=("What kind of case is this entry about?"), choices=NEGATIVE_CASE_REASONS_CHOICES, blank=True, ) socioeconomic_benefits = models.TextField( verbose_name=_("Socio-economic impacts"), blank=True ) negative_socioenvironmental_impacts = models.TextField( verbose_name=_( "Describe the socio-environmental impacts (positive and negative):" ), help_text=_( "Please provide a detailed description of the socio-environmental impacts" " (all relevant details, such as type of ecosystem, presence of any" " existing reserve in the area, biodiversity impacts, new protection of" " lands/waters, total geographic footprint of the project," " tenure system affected in the case of land grabs, etc.)." ), blank=True, ) isolated_or_widespread = models.TextField( verbose_name=_( "Is the project part of developments which are causing a cumulative effect?" ), help_text=_( "Is this an isolated project or are there similar projects in the same" " geographic area? If so, can you please describe them? Is there an" " analysis of cumulative or synergetic effects?" ), blank=True, ) key_actors_involved = models.TextField( verbose_name=_("Key actors involved (individual/organisational)"), blank=True ) project_status_detail = models.TextField( verbose_name=_("Current status of the case"), help_text=_( "Please describe the current situation and likely future scenarios." ), blank=True, ) obstacles_and_hindrances = models.TextField( verbose_name=_("Current status of the organizing process around this case"), help_text=_( "Please describe the status of the organizing process, including the obstacles and hindrances faced." ), max_length=512, blank=True, ) identified_partnerships = models.CharField( verbose_name=_("Identified partnerships"), help_text=_( "Are you, or the organizing process that you represent, looking for partnerships," " or have any clearly identified need? If so, please describe and we will try" " to connect you to appropriate partners." ), max_length=256, blank=True, ) # 3.2.1.9 negative_case_reasons_other = models.CharField( verbose_name=_("Other reason for negative case"), help_text=_( "For negative impacts you need to focus on substantive impacts on vulnerable groups." ), max_length=512, blank=True, ) # 3.2.4.1 when_did_organising_start = models.CharField( verbose_name=_("When did local organising efforts begin?"), help_text=_( "Before the project started? During project implementation?" " After project implementation? Please describe in your own words." ), max_length=512, blank=True, ) # 3.2.4.2 who_has_been_involved = models.TextField( verbose_name=_( "Which communities, groups and organisations have been involved?" ), blank=True, ) # 3.2.4.3 participation_mechanisms = models.TextField( verbose_name=_("What mechanisms of participation have been used?"), help_text=_( "e.g. direct action, local referendums, legal cases," " letters or petitions, etc." ), blank=True, ) # 3.2.7 wants_conversation_with_ojuso = models.BooleanField( verbose_name=_( "Would you like to have a conversation with the ojuso team?" ), help_text=_( "This would be a conversation about challenging or engaging related" " developers, companies and investors." ), default=False, ) ## # Contact details ## contact_email = models.EmailField(verbose_name=_("Email address"), blank=True) contact_phone = PhoneNumberField( verbose_name=_("Phone number"), help_text=_('Please include the international prefix, beginning with "+".'), blank=True, ) contact_website = models.URLField(verbose_name=_("Website"), blank=True) contact_twitter = models.CharField( verbose_name=_("Twitter username"), max_length=50, blank=True ) contact_facebook = models.URLField(verbose_name=_("Facebook page"), blank=True) contact_other = models.TextField( verbose_name=_("Other contact details"), blank=True ) ## # Uploads ## # 4.1 official_project_documents = models.ManyToManyField( "files.File", related_name="official_project_document_for", verbose_name=_("Official project documents"), help_text=_( "Please attach any legal or official documents that relate to the project." ), blank=True, ) # 4.2 other_documents = models.ManyToManyField( "files.File", related_name="other_document_for", verbose_name=_("Other documents"), help_text=_("Please attach any other documents that relate to the project."), blank=True, ) # 4.4 shown_on_other_platforms = models.BooleanField( verbose_name=_("Is this case study shown on other platforms?"), default=True ) # 4.4.1 shown_on_other_platforms_detail = models.TextField( verbose_name=_("Shown on other platforms - Detail"), help_text=_("Please provide links to other places the case study appears."), blank=True, ) objects = CaseStudyQuerySet.as_manager() def __str__(self): """The String representation of the case study. (Entry name with country name.)""" return "%s in %s" % (self.entry_name, self.country.name) def save(self, *args, **kwargs): """ Override the save method to create a slug when the model is created. Slug is only created and never modified as we are basing our URLs on it and don't want it to change - ever. """ if not self.pk: # Newly created object, so set slug self.slug = slugify(self.entry_name) super(CaseStudy, self).save(*args, **kwargs) def is_video_youtube(self): return self.video.count("youtube.com") > 0 def get_youtube_id(self): """Gets the 11 character YouTube video ID from the video field.""" return parse.parse_qs(parse.urlparse(self.video).query)["v"][0] def is_video_vimeo(self): return self.video.count("vimeo.com") > 0 def get_vimeo_id(self): """Gets the 11 number video ID from the video field.""" return parse.urlparse(self.video).path class Meta: verbose_name_plural = "case studies" class PointOfInterestQuerySet(models.QuerySet): def approved(self): return self.filter(approved=True) class PointOfInterest(models.Model): class Meta: verbose_name_plural = "points of interest" def __str__(self): return self.title objects = PointOfInterestQuerySet.as_manager() author = models.ForeignKey( User, models.SET_NULL, blank=True, null=True, editable=False ) date_created = models.DateTimeField(auto_now_add=True, null=False) slug = AutoSlugField(populate_from=["title"], editable=False) approved = models.BooleanField(default=False) title = models.CharField(max_length=128) location = models.PointField() synopsis = models.TextField() link = models.URLField()