o
    3phg                     @   s  d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlZG d	d
 d
ejZd dlmZ d dlmZ dd Zdd ZG dd dejZG dd dejZG dd dejZG dd dejZG dd dejZG dd dejZG dd dejZG dd  d ejZG d!d" d"ejZ G d#d$ d$ejZ!G d%d& d&ejZ"G d'd( d(ejZ#G d)d* d*ejZ$ee	ed+d,d- Z%G d.d/ d/ejZ&dS )0    )	timedelta)models)User)timezone)	post_save)receiver)settingsNc                       s  e Zd Zg dZeddZejddZe	 Z
e ZejdddZejddZejded	d
ZejddddZejdddZejddddZejddgddddZdd Z fddZdd Zedd Zedd Zedd  Zed!d" Zed#d$ Zed%d& Z ed'd( Z!  Z"S ))Event))upcomingUpcoming)ongoingOngoing)archivedArchived   hours   
max_lengthTnullblank
   r
   r   choicesdefaultzevent_banners/)	upload_tor   r   Fz5Enable this to allow users to register for this eventr   	help_textz>Facebook live stream URL. Will be shown when event is ongoing.r   r   r   )facebookFacebookz)Platform where the event will be streamed)r   r   r   r   r   c                 C      | j S Ntitleself r)   +/var/www/html/bloggers_ems/events/models.py__str__+      zEvent.__str__c                    s@   t  }| jrd| _n
| jrd| _nd| _t j|i | d S )Nr
   r   r   )r   nowis_upcomingstatus
is_ongoingsupersaver(   argskwargsr-   	__class__r)   r*   r2   .   s   z
Event.savec                 C   s   | j o| jS )z/Check if registration is allowed for this event)r.   registration_openr'   r)   r)   r*   can_register;   s   zEvent.can_registerc                 C   s   | j t kS )zCheck if the event is upcoming)	date_timer   r-   r'   r)   r)   r*   r.   ?   s   zEvent.is_upcomingc                 C   sP   t  }| jr| j|  ko| jkS   S | j| j }| j|  ko%|kS   S )z'Check if the event is currently ongoingr   r-   end_timer:   DEFAULT_EVENT_DURATIONr(   r-   event_end_timer)   r)   r*   r0   D   s
   zEvent.is_ongoingc                 C   s,   t  }| jr|| jkS | j| j }||kS )zCheck if the event has endedr;   r>   r)   r)   r*   is_archivedN   s
   
zEvent.is_archivedc                 C   s
   t | jS )z%Check if event has a valid stream URL)bool
stream_urlr'   r)   r)   r*   
has_streamX   s   
zEvent.has_streamc                 C   sD   | j sdS d| jv rdtj| j dS tj| j}d| dS )z*Convert regular URL to embedded URL formatNz/videos/z0https://www.facebook.com/plugins/video.php?href=z%&show_text=false&width=500&height=282z/https://www.facebook.com/plugins/post.php?href=z&show_text=true&width=500)rC   rB   urllibparsequote)r(   encoded_urlr)   r)   r*   embedded_stream_url_   s   
zEvent.embedded_stream_urlc                 C   s   | j sdS | jS )z)Get the direct URL for the video platformN)rC   rB   r'   r)   r)   r*   
direct_urlm   s   zEvent.direct_urlc                 C   r#   )z8Check if stream should be shown (has URL and is ongoing))rC   r'   r)   r)   r*   stream_availablet   s   zEvent.stream_available)#__name__
__module____qualname__STATUS_CHOICESr   r=   r   	CharFieldr&   	TextFielddescriptionDateTimeFieldr:   r<   venuer/   
ImageFieldbanner_imageBooleanFieldr8   URLFieldrB   stream_platformr+   r2   r9   propertyr.   r0   r@   rC   rH   rI   rJ   __classcell__r)   r)   r6   r*   r	      sP    


	
	


r	   )ValidationError)get_image_dimensionsc              
   C   s   | rbt | \}}d}d}d}||k s||k r'td| d| d| d| d	||ks/||kr@td| d| d| d| d	| j|krStd	| jd
 d
 dd||krdtd| d| dd S d S )Ni  i  i  P z"Image dimensions must be at least xz pixels. Your image is z pixels.zImage dimensions cannot exceed z0Image file size cannot exceed 2MB. Your file is i   z.1fzMB.z<Image must be square (same width and height). Your image is )r\   r[   size)imagewhmin_dimensionmax_dimensionmax_sizer)   r)   r*   validate_speaker_photo|   sF   
re   c                 C   s   | sd S g d}|   D ]8}||vrtd| |dkr,| | r,| | ds,td|dv rD| | rD| | dsDt|  dqd S )	N)twitterlinkedingithubwebsitezInvalid social media key: rf   @z Twitter handle must start with @)rg   rh   ri   )zhttp://zhttps://z5 must be a full URL starting with http:// or https://)keysr[   
startswithr&   )valuerequired_keyskeyr)   r)   r*   validate_social_media   s   rp   c                   @   s   e Zd ZejddZejddddZejddZej	dde
gd	d
ZejddddZejdddZejedegddZejeddddZejddZdd Zdd Zdd ZdS )Speakerd   r   Tz.Job title or role, e.g. "Full Stack Developer"r   r   r   z=A brief description of the speaker's background and expertiser   zspeaker_photos/z=Square image, minimum 400x400px, maximum 1200x1200px, max 2MB)r   r   
validatorsr   r   z.Organization or company the speaker representsz$Personal or professional website URLr   r   zSocial media links in JSON format. Example: {"twitter": "@username", "linkedin": "https://linkedin.com/in/username", "github": "https://github.com/username", "website": "https://example.com"})r   r   ru   r   speakersz'Events this speaker is participating inrelated_namer   r   auto_now_addc                 C   s0   | j r| j dr| j d d}d| S dS )z(Get the full Twitter URL from the handlerf   rj   zhttps://twitter.com/N)social_mediagetlstrip)r(   handler)   r)   r*   get_twitter_url   s   
zSpeaker.get_twitter_urlc                 C   s   g }| j rJ|   }r||ddd | j d }r%||ddd | j d }r6||dd	d | jp>| j d
 }rJ||ddd |S )z1Get all social media links in a structured formatz
bi-twitterTwitter)urliconnamerg   zbi-linkedinLinkedInrh   z	bi-githubGitHubri   zbi-globeWebsite)r|   r   appendr}   ri   )r(   linksrf   rg   rh   ri   r)   r)   r*   get_social_links   s6   zSpeaker.get_social_linksc                 C   r#   r$   r   r'   r)   r)   r*   r+      r,   zSpeaker.__str__N)rK   rL   rM   r   rO   r   r&   rP   biorT   re   photoorganizationrW   ri   	JSONFielddictrp   r|   ManyToManyFieldr	   eventsrR   
created_atr   r   r+   r)   r)   r)   r*   rq      sR    rq   c                   @   sb   e Zd ZejeejddZejddZ	e
 Ze ZejeddddZdd	 ZG d
d dZdS )Agendaagendas	on_deletery   r   r   Tz?Speakers for this session. Leave empty if no specific speakers.rx   c                 C   r#   r$   )session_titler'   r)   r)   r*   r+     r,   zAgenda.__str__c                   @      e Zd ZdgZdZdZdS )zAgenda.Metasession_timezAgenda ItemzAgenda ItemsNrK   rL   rM   orderingverbose_nameverbose_name_pluralr)   r)   r)   r*   Meta      r   N)rK   rL   rM   r   
ForeignKeyr	   CASCADEeventrO   r   rR   r   rP   rQ   r   rq   rw   r+   r   r)   r)   r)   r*   r      s    r   c                       s   e Zd ZejeejddZejddZ	ej
dddddZe Ze Zg d	Zejd
eddZejeejddddZejejdZejddZdd Z fddZedd Zedd Zedd Zedd Zedd Z   Z!S )CallForProposalcfpsr   r   r   zcfp_images/Tz Image to display on the CFP cardr   r   r   r   ))openOpen)closedClosedunder_reviewzUnder Review   r   r   created_cfpsr   r   r   ry   )r   auto_nowc                 C   r#   r$   r%   r'   r)   r)   r*   r+   #  r,   zCallForProposal.__str__c                    sH   t  }| jdkr|| jks| jjsd| _nd| _t j|i | d S )Nr   r   r   )r   r-   r/   submission_deadliner   r.   r1   r2   r3   r6   r)   r*   r2   &  s   
zCallForProposal.savec                 C   s$   t  }| jdko|| jko| jjS )z$Check if CFP is open for submissionsr   )r   r-   r/   r   r   r.   )r(   r-   r)   r)   r*   is_open0  s   
zCallForProposal.is_openc                 C   s   | j dkpt | jkS )zCheck if CFP is closedr   )r/   r   r-   r   r'   r)   r)   r*   	is_closed:  s   zCallForProposal.is_closedc                 C   s
   | j dkS )zCheck if CFP is under reviewr   )r/   r'   r)   r)   r*   is_under_review?  s   
zCallForProposal.is_under_reviewc                 C   s   | j rdS | jr
dS dS )z,Return Bootstrap badge class based on statuszbg-infoz
bg-successz	bg-danger)r   r   r'   r)   r)   r*   status_badge_classD  s
   z"CallForProposal.status_badge_classc                 C   s   | j r| jS dS )z/Return submission deadline for timeuntil filterN)r   r   r'   r)   r)   r*   time_remainingN  s   zCallForProposal.time_remaining)"rK   rL   rM   r   r   r	   r   r   rO   r&   rT   r_   rP   rQ   rR   r   rN   r/   r   SET_NULL
created_byr   r-   r   
updated_atr+   r2   rY   r   r   r   r   r   rZ   r)   r)   r6   r*   r     s:    

	


	r   c                   @   s@   e Zd ZdZejdddZejddZdd Z	G dd	 d	Z
d
S )SessionTypez9Model for session types that can be configured from adminrr   Tr   uniquer   c                 C   r#   r$   r   r'   r)   r)   r*   r+   Z  r,   zSessionType.__str__c                   @   s   e Zd ZdgZdS )zSessionType.Metar   NrK   rL   rM   r   r)   r)   r)   r*   r   ]  s    
r   N)rK   rL   rM   __doc__r   rO   r   rP   rQ   r+   r   r)   r)   r)   r*   r   U  s    r   c                   @   sJ  e Zd ZejeejddZejdddZ	ejdddZ
ejddZejdd	d
dZejddZejeejddZejddZddgZejdeddZejdd	d	ddZejd	ddZejeejddZg dZejdeddZejd	dZejd	dZejd	d Zejeejd	d	d!d"Z ejd	d	d#Z!d$d% Z"d,d'd(Z#G d)d* d*Z$d+S )-Proposal	proposalsr   r   zYour organization namer   r      zYour contact phone numberr   Tz$Optional sub-theme for your proposalrs   z<Provide a clear and concise description of your presentationrt   z.What participants will learn from your session)yeszYes, I will sponsor my session)nozNo, I need sponsorship   zAre you sponsoring your session or do you need sponsorship? Note: Priority is given to session proposers who will contribute to the event costs)r   r   r   zproposal_documents/z,Additional supporting documents (PDF format)r   zAAny additional information you'd like to share with the reviewersrv   submitted_proposals))	submitted	Submittedr   )acceptedAccepted)rejectedRejectedr   r   r   rz   r   r   reviewed_proposalsr   r   c                 C   r#   r$   r%   r'   r)   r)   r*   r+     r,   zProposal.__str__ c                 C   s(   || _ || _|| _t | _|   d S r$   )r/   reviewer_notesreviewed_byr   r-   reviewed_atr2   )r(   reviewerr/   notesr)   r)   r*   review  s
   
zProposal.reviewc                   @   s"   e Zd Zg dZdgZdZdZdS )zProposal.Meta)r&   	submittercfpz-submitted_atr   	ProposalsN)rK   rL   rM   unique_togetherr   r   r   r)   r)   r)   r*   r     s
    r   N)r   )%rK   rL   rM   r   r   r   r   r   rO   organisationcontact_numberr&   	sub_themerP   abstractr   session_typelearning_objectivesSPONSORSHIP_CHOICESsponsorship	FileFieldsupporting_documentadditional_notesr   r   rN   r/   rR   submitted_atr   r   r   r   r   r+   r   r   r)   r)   r)   r*   r   a  sR    
r   c                   @   sT   e Zd ZdZejdddZejddddZejdd	d
dZdd Z	G dd dZ
dS )PublicationTypez$Model for managing publication types2   Tr   zbi-file-earmarkz0Bootstrap icon class (e.g., bi-file-earmark-pdf))r   r   r   r   zFComma-separated list of allowed file extensions (e.g., .pdf,.doc,.ppt)z.pdf,.doc,.docx,.ppt,.pptx)r   r   r   c                 C   r#   r$   r   r'   r)   r)   r*   r+     r,   zPublicationType.__str__c                   @      e Zd ZdZdZdgZdS )zPublicationType.MetazPublication TypezPublication Typesr   NrK   rL   rM   r   r   r   r)   r)   r)   r*   r         
r   N)rK   rL   rM   r   r   rO   r   r   allowed_extensionsr+   r   r)   r)   r)   r*   r     s    r   c                   @   s   e Zd ZdZejddZejddZej	e
ejddZej	eejddZejd	d
dZejdddZejdddZdd Zdd Zdd ZG dd dZdS )Publicationz7Model for standalone publications not tied to proposals   r   z$Brief description of the publicationrt   z&Who authored/uploaded this publication)r   r   zType of publicationzpublications/zUpload your publication filer   r   Tz(When this publication was made available)r{   r   z*Make this publication visible to all usersr   c                 C   r#   r$   r%   r'   r)   r)   r*   r+     r,   zPublication.__str__c                 C   sv   | j r| j js	dS z'| j j| j jsW dS | jr.t }|tjdd }| jj|kr.W dS W dS  t	y:   Y dS w )z<Check if the publication meets requirements for being publicF   r   T)
filer   storageexistsr   r   r-   r   r:   	Exception)r(   r-   two_hours_agor)   r)   r*   can_be_published  s   zPublication.can_be_publishedc                 C   s   t | j| jdS )z0Return the display name for the publication typeUnknown)r   PUBLICATION_TYPESr}   publication_typer'   r)   r)   r*   get_publication_type_display  s   z(Publication.get_publication_type_displayc                   @   r   )zPublication.Metaz-published_atr   PublicationsNr   r)   r)   r)   r*   r     r   r   N)rK   rL   rM   r   r   rO   r&   rP   r   r   r   r   authorr   PROTECTr   r   r   rR   published_atrV   	is_publicr+   r   r   r   r)   r)   r)   r*   r     s@    r   c                       sl   e Zd ZejeejddZejddZ	ej
ddZej
dddd	Z fd
dZdd ZG dd dZ  ZS )Gallerygalleryr   zgallery_images/)r   r   r   r   T)r   r   r   c                    s6   | j r| js| j jdd | _t j|i | d S )N/)r_   original_filenamer   splitr1   r2   r(   r4   r5   r6   r)   r*   r2     s   zGallery.savec                 C   s   | j j d| j S Nz - )r   r&   captionr'   r)   r)   r*   r+        zGallery.__str__c                   @   s"   e Zd ZdZdZdgZddgZdS )zGallery.MetazGallery ImagezGallery Imagesz-idr   r  N)rK   rL   rM   r   r   r   r   r)   r)   r)   r*   r     s
    r   )rK   rL   rM   r   r   r	   r   r   rT   r_   rO   r  r  r2   r+   r   rZ   r)   r)   r6   r*   r     s    r   c                   @   s   e Zd ZejdddZejdddZejddd	d
Zej	dddZ
ejdddZejddZejddZG dd dZdd ZdS )CarouselImagerr   !A descriptive title for the imager   z	carousel/zDRecommended size: 1920x1080px. Images will be cropped/scaled to fit.r   r   Tz*Optional caption to display over the imagers   z0Only active images will be shown in the carouselr   r   z+Images will be displayed in ascending orderrz   r   c                   @   s   e Zd ZddgZdZdZdS )zCarouselImage.Metaorderz-created_atzCarousel ImagezCarousel ImagesNr   r)   r)   r)   r*   r   -  s    r   c                 C   r#   r$   r%   r'   r)   r)   r*   r+   2  r,   zCarouselImage.__str__N)rK   rL   rM   r   rO   r&   rT   r_   r  rV   	is_activePositiveIntegerFieldr  rR   r   r   r   r+   r)   r)   r)   r*   r
    s.    r
  c                   @   s   e Zd ZdgZejdedddZejdddZejd	d
dZ	ejddddZ
ejdddZejddZejddZG dd dZdd ZdS )SectionImage)join_communityzJoin Community Sectionr   Tz.The section where this image will be displayed)r   r   r   r   rr   r  r   zsection_images/z3Image for the section (recommended size: 800x600px)r   r   zOptional caption for the imagers   z Only active images will be shownr   rz   r   c                   @   s   e Zd ZdZdZdS )zSectionImage.MetazSection ImagezSection ImagesN)rK   rL   rM   r   r   r)   r)   r)   r*   r   U  s    r   c                 C   s   |    d| j S r  )get_section_displayr&   r'   r)   r)   r*   r+   Y  r	  zSectionImage.__str__N)rK   rL   rM   SECTION_CHOICESr   rO   sectionr&   rT   r_   r  rV   r  rR   r   r   r   r+   r)   r)   r)   r*   r  6  s6    r  c                   @   s|   e Zd ZejdddZejdddZejdddd	Z	ej
dd
dZejdddZejdddddZG dd dZdd ZdS )Sponsorrr   zName of the sponsorr   z	sponsors/z*Sponsor logo (recommended size: 300x200px)r   TzURL to sponsor's websiter    z,Whether to show this sponsor in the carouselr   r   z;Order in which to display the sponsor (lower numbers first)r	   sponsorsz&Events this sponsor is associated withrx   c                   @      e Zd ZddgZdS )zSponsor.Metar  r   Nr   r)   r)   r)   r*   r   w      r   c                 C   r#   r$   r   r'   r)   r)   r*   r+   z  r,   zSponsor.__str__N)rK   rL   rM   r   rO   r   rT   logorW   ri   rV   r  r  r  r   r   r   r+   r)   r)   r)   r*   r  ]  s6    r  c                       sZ   e Zd Zg dZejdeddZejedddZ	dd Z
 fd	d
ZG dd dZ  ZS )Role))adminAdmin)editorEditor)attendeeAttendeer   T)r   r   r   zStore role-specific permissions)r   r   r   c                 C   s   |   S r$   )get_name_displayr'   r)   r)   r*   r+     s   zRole.__str__c                    sf   | j s(| jdkrddddddd| _ n| jdkr!ddddd| _ ndddd| _ t j|i | d S )Nr  T)can_manage_eventscan_manage_userscan_manage_rolescan_manage_gallerycan_approve_proposalscan_view_reportsr  F)r!  r$  r%  r&  can_register_eventscan_submit_proposalscan_view_events)permissionsr   r1   r2   r  r6   r)   r*   r2     s(   



z	Role.savec                   @   r   )z	Role.Metar  Rolesr   Nr   r)   r)   r)   r*   r     r   r   )rK   rL   rM   ROLE_CHOICESr   rO   r   r   r   r+  r+   r2   r   rZ   r)   r)   r6   r*   r  ~  s    r  c                   @   s   e Zd ZejeejdZeje	ejdZ
ejddZejdddZejdddZejdddZejdd	Zejdd
Zdd Zdd Zdd ZdS )UserProfiler   Tr   r   )r   r   r   zprofile_pictures/)r   r   rz   r   c                 C   s   | j j dS )Nz
's Profile)userusernamer'   r)   r)   r*   r+     s   zUserProfile.__str__c                 C      | j jrdS | j jrdS dS )z6Get the user's role display name based on permissions.	SuperuserStaffr  r0  is_superuseris_staffr'   r)   r)   r*   get_role_display  
   zUserProfile.get_role_displayc                 C   r2  )z>Get the appropriate Bootstrap color class for the user's role.primaryinfo	secondaryr5  r'   r)   r)   r*   get_role_color  r9  zUserProfile.get_role_colorN)rK   rL   rM   r   OneToOneFieldr   r   r0  r   r  rolerP   r   rO   r   phone_numberrT   profile_picturerR   r   r   r+   r8  r=  r)   r)   r)   r*   r.    s    	r.  )senderc                 K   s@   |rt jjddddddid\}}tjj|d|id dS dS )	z=Create a UserProfile for new users with default attendee roler  r+  Tr'  )r   defaultsr?  )r0  rC  N)r  objectsget_or_creater.  )rB  instancecreatedr5   attendee_role_r)   r)   r*   create_user_profile  s   

rJ  c                   @   s   e Zd ZejeejddZejeejdZ	g dZ
ejde
ddZejdd	Zejddd
ZejddZG dd dZdd Zdd ZdS )Registrationregistrationsr   r/  ))
registered
Registered)attendedAttended)	cancelled	Cancelledr   rM  r   Trz   r   r   c                   @   r  )zRegistration.Metar   r0  N)rK   rL   rM   r   r)   r)   r)   r*   r     r  r   c                 C   s   | j j d| jj S r  )r0  r1  r   r&   r'   r)   r)   r*   r+     s   zRegistration.__str__c                 C   s   d| _ t | _|   d S )NrO  )r/   r   r-   attendance_dater2   r'   r)   r)   r*   mark_as_attended  s   
zRegistration.mark_as_attendedN)rK   rL   rM   r   r   r	   r   r   r   r0  rN   rO   r/   rR   registration_daterS  rP   r   r   r+   rT  r)   r)   r)   r*   rK    s    rK  )'datetimer   	django.dbr   django.contrib.auth.modelsr   django.utilsr   django.db.models.signalsr   django.dispatchr   django.confr   urllib.parserD   Modelr	   django.core.exceptionsr[   django.core.files.imagesr\   re   rp   rq   r   r   r   r   r   r   r   r
  r  r  r  r.  rJ  rK  r)   r)   r)   r*   <module>   s:    nPHAG'!-

