
    u+h9F                     ~   d Z ddlZddlZddlmZ ddlZddl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ddlmZ dd	lmZ dd
lmZ ddlmZmZmZ ddlmZ ddlmZ  ej>                  g d      Z d Z!dZ"djG                   e!             Z$de%de%de%fdZ&de%de%fdZ'de%de%de%fdZ( eejR                  ejT                        Z+dZ,dZ-de%fdZ.de%de%fdZ/ G d  d!ej`                        Z1 G d" d#ej`                        Z2 G d$ d%ej`                        Z3d& Z4 G d' d(ej`                        Z5 G d) d*e5      Z6d+ Z7y),zn
MarkdownxFields can handle what?

Special links: {LA-LinearAlgebra <optional link text> <#optional anchor>}

    N)ZoneInfo)Path)models)get_template)MarkdownxField)	mark_safe)FileSystemStoragesettings)CourseFileKind
CourseFile)	get_epoch)CourseRecord)zcode-friendlyzfenced-code-blocks	numberingtables)extrasc                      g d} | S )N)z(<a href="https?://saeta.physics.hmc.edu/z([a-z]\d\d\d)/z([A-Z]{2}-.*?)\.htmlz	(|#[^ ]*)z"(| target="[^"]*")z>([^<]*)</a> )segmentss    !/var/www/djphys/courses/models.pymake_long_regexr   %   s    H O    z2\{([A-Z]{2}-[-A-Za-z0-9]+) ?([^#}]*) ?(|#[^ }]*)\} torder_fieldreturnc                     dt         ffd}t        j                  t        || t        j                        }t        |      S )zG
    Replace short urls of the form {FO-Series ...} to valid html.
    r   c                     | j                         \  }}}d d| d}|s t        |d|j                  d      z   d        }d| | d| d}|S )	Nzhttps://saeta.physics.hmc.edu//z.html   -	<a href="z" target="_pages"></a>)groupsdecamelindex)mpagetitleanchorpageurlurlr   s         r   makelongz#convert_shorturls.<locals>.makelong:   si    hhjeV2;-qeLDTZZ_!4!567E'6(*<UG4H
r   flags)strresubREGEX_SHORTMr   )r   r   r.   txts    `  r   convert_shorturlsr7   5   s3    
s  &&h
6CS>r   c                     dt         fd}t        j                  t        || t        j                  t        j
                  z        }|S )z.
    Substitute short urls for long ones.
    r   c                 f    | j                         \  }}}}}| }|r|d| z  }|r|d| z  }d|z  S )N z{%s})r%   )r(   r   r)   r+   targetr*   gutss          r   	makeshortz#convert_longurls.<locals>.makeshortJ   sO    3488:0T665awKDaxL D}r   r/   )r1   r2   r3   
REGEX_LONGr5   DOTALL)r   r=   r6   s      r   convert_longurlsr@   F   s6      &&Y		1A
BCJr   sc                     t         j                  |       }t        j                  dd|t        j                  t        j
                  z         }t        ||      S )Nz<pre>(.*?)</pre>z<pre class="latex">\1</pre>r/   )
markdownerconvertr2   r3   r5   r?   r7   )rA   r   r   s      r   mdrE   W   sH    1A
&	ddRYY	A Q,,r   )locationbase_url))lLecture)r
Recitation)bLab)eExam)hHoliday))CzClaremont only)FzPhysics faculty only)1Anyone)LzOnly registered usersr6   c                     d }| d   }d}|t        |       k  r: || |         r || |dz
           s|dz  }|| |   z  }|dz  }|t        |       k  r:|S )z$Split camel case into separate wordsc                 X    t        d      t        |       cxk  xr t        d      k  S c S )NAZ)ord)xs    r   capzdecamel.<locals>.cap   s$    3x3q6-SX----r   r   r!   r:   )len)r6   r]   r   ns       r   r&   r&   }   sn    . 	AA	A
c#h,s1v;s3q1u:HA	SV	Q	 c#h,
 Hr   c                     d }d}t        j                  ||| t         j                  t         j                  z        }t	        ||      S )a  
    Scan txt looking for link text to convert into actual hyperlinks.
    These are in two forms:
    1) https?://[^ "\']*
    2) \{[A-Z]{2}-[^ }]*\}   e.g., {FO-FourierSeries}

    Form the links and return the resulting string after marking it safe.
    c                     | j                         \  }}|j                  d      }|d   j                  d      d   }d| | d| d}|S )Nr    .r   r#   ">r$   )r%   split)r(   protocoladdressfieldslinktextlinks         r   makelinkzmake_links.<locals>.makelink   sV    HHJ's#":##C(+8*WIRz>r   z(<!href=")(https?://)([^ "\']*)r/   )r2   r3   r5   Ir7   )r   r   rk   regexr6   s        r   
make_linksrn      s;     /E
&&!244"$$;
7CS+..r   c                       e Zd Z ej                  edej                        Z ej                  eddej                        Z	 ej                  ddd      Zd Zd Zd Zd	 Zdd
Zy)
CourseSiteT)null	on_delete)blankrq   rr   z4Define any CSS styles here you wish used on the site)rq   rs   	help_textc                 4    d| j                   j                   S )NzCourseSite for )coursenameselfs    r   __str__zCourseSite.__str__   s     !1!1 233r   c                    t         j                  j                  | j                  |j                  |j
                        }|j                         dk(  r|j                  |j                        }|j                         dk(  r|d   S y )N)rv   yearsemester   )partr!   r   )r   objectsfilterrv   r|   r}   countportion)ry   epochcrss      r   course_recordzCourseSite.course_record   sm    ""))/4zzENN * T99;!**%--*0C99;!q6Mr   c           	      H   t        j                  dt         j                        }|j                  |      }t	               }|D ]V  }t        j
                  d|      }t        |j                  d            }|dz  }||vr|g||<   C||   j                  |       X |j                         D ]B  \  }}	dt        |	       d| d}
|	d   j                  d	      }|	d   d
| |
z   |	d   |d
 z   |	d<   D d}|j                  |      }|j                  d      }|d
| |dd||j                  d      |j                  d       dg}|j                         D ]  \  }}	|	D ]  }|j                  |         |j                  ||j                  d      d
        dj                  |      S )a  Add a column for the week of the semester.
        The source text has a number of <tr> lines that include a field
        week="n". Each time that number changes, we need to include a
        narrow column that spans the appropriate number of rows to show the
        full week on the left. We need to extract what's inside the
        <tr> </tr>, so we can add a multicolumn td on the first row of a
        week.
        z(<tr class=.*?</tr>)zweek="(\d*)"r!   
z<td rowspan="zX" style="width: 16px; padding: 0px; vertical-align: middle;"><div class="rot">Week&nbsp;z</div></td>
r   z<tdNz<table class="calendar table">z</table>z
<tr>
z<td class="week">&nbsp;</td>
z<th>z</tr>z</tr>
r   )r2   compiler?   findalldictsearchintgroupappenditemsr^   r'   join)ry   srcpatrowsweeksrJ   r(   weekkv	to_insertwheretable_startn_table_startn_table_endchunksdays                    r   	add_weekszCourseSite.add_weeks   s    jj0"))<{{3 	&A		/1-Aqwwqz?DIA5  cdd""1%	& KKM 	;DAq') (klmknn{}IaDJJu%EQ4<)+ad56l:AaD		; 7		+.ii
+ ,		&!#))G"45
 KKM 	#DAq #c"#	# 	c#))J/012wwvr   c           
      h   ddl m} ddlm} | j	                  t        |            }|sy t        j                  j                  |      j                  d      }t        d      }g }t               } ||j                        }	|D ]L  }
|
j                  }||vrd||<   ||xx   dz  cc<   |j                  |j                  |
||   ||	d             N t        d	      }t        ||
      } ||j                        r
 |       |d<   |j                  |      }| j!                  |      }t#        |      S )Nr   )
is_faculty)LoadScheduleForm)r   datezcourses/meeting.htmlr!   )meetingnumberrequesteditablezcourses/calendar.html)meetingsr   loadform)people.funcsr   courses.formsr   r   r   Meetingr   r   order_byr   r   usersession_typer   renderr   r   )ry   r   r   r   
course_recr   tempmeetscountersr   r(   stdicr   
with_weekss                  r   calendarzCourseSite.calendar   s,   +2''	'(:;
??))$ * &&.hv&6 	236gll+ 	+AB! RLALLL"'%)* +	+ 34E<gll#.0C
Okk# ^^C(
$$r   c                 
   |j                         \  }}dddddd}||z   |z   }t        dd      D ]  }	||	   }
|
|v s|	|j                         z
  }|dk  r|d	z  }|t        j                  |
      z   }||k  sIg }|
|v r|j                  d       |
|v r|j                  d       |
|v r|j                  d       |D ]$  }t        j                  j                  |||       & |t        j                  d	
      z  }||k  r y )Nr5   TWRrS   )r   r!   r~         r         )daysrH   rJ   rL   )r   r   r   )	spanrangeweekdaydatetime	timedeltar   r   r   create)ry   r   lecturesrecitationslabsstartfinishdaymap
everythingr   	dayletterdtdstypesr   s                  r   make_calendarzCourseSite.make_calendar  s&   %**,vSSSS9+d2
A; 	4CsIJ&5==?*6!GBH..B776kF H,c* K/c* D(c*$ H..]<>Q / HH ++33A 6k	4r   N)r   r   r   )__name__
__module____qualname__r   
ForeignKeyr   CASCADErv   r   logo	TextFieldstylerz   r   r   r   r   r   r   r   rp   rp      sq    VvDFNNKF6Zt"&&..BDF$d']_E4-^%B4r   rp   c                       e Zd Z ej                         Z ej                  d      Z ej                  d      Z	 ej                  dd      Z
 ej                  dd      Zd Zed        Zed        Zy	)
URLTauto_now_add   )
max_lengthrs   rq   c                     | j                   S N)r-   rx   s    r   rz   zURL.__str__<  s    xxr   c                 V    d| j                    d| j                   d}t        |      }|S )z9Write an entry in a script file to describe this url linkr#   rd   r$   )r-   descriptionr@   )ry   longshorts      r   scriptz
URL.script?  s2     488*Bt'7'7&8= &r   c           	          ddl m} d|j                   d}t        d| j                   d| d| j
                   d      S )	Nr   r
   z
<img src="zico/link.png" class="icon">r#   z" target="_new">z&nbsp;z
</a>&nbsp;)django.confr   
STATIC_URLr   r-   r   )ry   r   icon_urls      r   rj   zURL.linkF  sX    ( ! ;=z!12 0 01=
 	
r   N)r   r   r   r   URLFieldr-   DateTimeFielddate_posted	CharFieldr   release_timerelease_untilrz   propertyr   rj   r   r   r   r   r   5  s    
&//
C&&&&D9K"&""c2K'6''d>L(F((t$?M   
 
r   r   c                   0   e Zd Z ej                  eej                        Z ej                  de	      Z
 ej                         Z ej                  ddd      Z ej                  ddd      Z ej                  ddd      Z ej                  ddd      Z edd      Z ej&                  d	      Z ej*                  ed
      Zed        Zd Zd Zd Zd Zd Zd Zed        Z d Z!d Z"ed        Z#ed        Z$ed        Z% G d d      Z&y)r   rr   r!   )r   choicesd   Tr   rs   rq   r   F)default)rs   c                 .    | j                   j                  S r   )r   rv   rx   s    r   rv   zMeeting.course^  s    !!(((r   c                    dj                  | j                  j                  | j                  | j	                               }| j
                  r|dj                  | j
                        z  }| j                  r|dj                  | j                        z  }| j                  r|dj                  | j                        z  }|S )Nz{0} {1} {2}z: {0}z, Reading: {0}z, Homework due: {0})formatrv   r   r   get_session_type_displaytopicreadinghomework)ry   rA   s     r   rz   zMeeting.__str__b  s      !8!8!%D,I,I,KM::

++A<<!((66A==&--dmm<<Ar   c                 8    | j                   j                  |      S r   )r   strftime)ry   fs     r   r   zMeeting.formatm  s    yy!!!$$r   c                 $    | j                  d      S )Nz%Ar   rx   s    r   DayNamezMeeting.DayNamep      {{4  r   c                 $    | j                  d      S )Nz%ar  rx   s    r   DayzMeeting.Days  r	  r   c                 $    | j                  d      S )Nz%Br  rx   s    r   MonthzMeeting.Monthv  r	  r   c                 $    | j                  d      S )Nz%br  rx   s    r   monthzMeeting.monthy  r	  r   c                 $    | j                  d      S )Nz%Y-%m-%dr  rx   s    r   isozMeeting.iso|  s    {{:&&r   c                 v    dj                  | j                  j                  | j                  j                        S )Nz{0}/{1})r   r   r  r   rx   s    r   
short_formzMeeting.short_form  s%    		??r   c                     i }dD ]<  }t        | |      st        t        | |      | j                  j                        ||<   > |S )N)r  r  exam)getattrr7   rv   r   )ry   r   r   s      r   rh   zMeeting.fields  sK    0 	?AtQ*D!$dkk&=&=?A	? 
r   c                 V    t        | j                  | j                  j                        S r   )rE   notesrv   r   rx   s    r   notes_mdzMeeting.notes_md  s    $**dkk5566r   c                 .    | j                   j                  S r   )r   r|   rx   s    r   r|   zMeeting.year  s    yy~~r   c                     | j                   j                  j                  }| j                  |z
  }d|j                  dz  z   }|S )zy
        Attempt to determine the number of the week in the semester
        that this meeting's date occurs in.
        r!   r   )r   r   start_r   r   )ry   r   r   r   s       r   r   zMeeting.week  s@     ""((//ii%388q= r   c                       e Zd ZdgZy)Meeting.Metaz-dateN)r   r   r   orderingr   r   r   Metar    s	    ;r   r   N)'r   r   r   r   r   r   r   r   r   SESSION_TYPEr   	DateFieldr   r   r  r  r  r   r  BooleanFieldhideManyToManyFieldr   urlsr   rv   rz   r   r  r  r  r  r  r  rh   r  r|   r   r   r   r   r   r   r   Q  s]   %F%%lfnnMM#6##q,GL6DF4dCEv3dFHf#TEG6s$TBDD1E6u-D!6!!#T2D) )	%!!!! ' '@ 7 7     r   r   c                    t        | t              r| j                  j                  }|j                  j
                  }|j                  }|j                  }|j                  }|dk(  rd}dj                  |||      }t        j                  j                  d||      }nd}t        j                  j                  ||      }	|	S )Nar   z	{0}{1}{2}coursesunknown)
isinstanceMeetingFiler   r   rv   r   r|   r}   r   r   ospathr   )
objfilenamecreccnamer|   r}   r   ysemfolder	full_paths
             r   FileLocationr6    s     #{#{{((''yy==))c>G!!$':i5VX.Ir   c                      e Zd Z ej                  dddej
                        Z ej                  d      Z ej                  e	ej
                        Z
 ej                  ee      Z ej                  ddd      Z ej                  d	ed
      Z ej                  dd      Z ej                  dd      Zd Zd Zd Zd Zed        Zed        Zed        Zd Zy)SecureCourseFilez	auth.UserT)rq   rs   rr   r   r   )	upload_tostorage   r   r!   rT   )r   r   r   )rq   rs   c                     | j                   r$t        | j                         dkD  r| j                   n| j                  }dj                  | j                  |      S )Nr   z	{0} - {1})r   r^   documentr   kind)ry   extras     r   rz   zSecureCourseFile.__str__  sN    $($4$4: !:"  '+}} 	!!$))U33r   c                 6    | j                   xs | j                  S r   )r   r   rx   s    r   
has_windowzSecureCourseFile.has_window  s      6D$6$66r   c                     t         j                   j                  t        d            }| j                  r|| j                  k  ry| j                  r|| j                  kD  ryy)NUTCFT)r   nowr   r   r   )ry   rD  s     r   	in_windowzSecureCourseFile.in_window  sQ    ##HUO4t'8'8!8#(:(:":r   c                     |j                   j                  ry| j                  dk(  r|j                  d   sy| j	                         S )NTrR   	ClaremontF)r   is_authenticatedaccesssessionrE  )ry   r   s     r   
has_accesszSecureCourseFile.has_access  s:    <<((;;#??;/~~r   c                     t         j                  j                  t        | j                              d   }|dd  j                         }dddddddddddd	d
dd}	 ||   }dj                  |      }|S #  d}Y xY w)Nr!   excelwordjpgnbpdfpngtexr6   ipynbrj   )xlsxlsxdocdocxrO  jpegrP  rQ  rR  rS  latexr6   rT  htmlunkzico/{0}.png)r-  r.  splitextr1   r=  lowerr   )ry   extmappingicoicons        r   rb  zSecureCourseFile.icon  s    ggs4==1215!"gmmo
 	#,C ##C(	Cs   A3 3A9c                 r    t         j                  j                  dj                  | j                              S )Nz/c/private/{0})urllibparsequoter   r=  rx   s    r   r-   zSecureCourseFile.url  s'    ||!!"2"9"9$--"HIIr   c                     	 | j                   j                  | j                   j                  | j                   j                  }}}| d| d| | j                   j	                  d       S #  Y yxY w)Nr    z %H:%Mr   )r   r|   r  r   r  )ry   yr(   r   s       r   showreleasezSecureCourseFile.showrelease  so    	'',,d.?.?.E.EtGXGXG\G\!qAS!AaS!2!2!;!;H!E FGG	s   A&A) )A-c                 @   | j                   r$t        | j                         dkD  r| j                   n| j                  }|j                  j                  rdnd}| j                         r|| j                         rdndz  }d}| j                         r0| j                         s |j                  dd| j                   d	      }t        | j                  j                        j                         j                  }t        j                  j                  |t        d
            }|j!                  d      }t#        j$                  dd|      }|j                  dd| d      }|j'                  | j(                  |t*        j,                  | j.                  |      }t1        |      S )Nr   profstudentz	 inwindowz
 outwindowzF<a href="{0}" class="{1}"><img src="{2}{3}" class="icon">&nbsp;{4}</a>r$   z (z)</a>zAmerica/Los_Angelesz%m/%d/%y %H:%Mz0(\d)z\1z%</a>&nbsp;&nbsp;<span class="fdate">(z
)</span>  )r   r^   r=  r   rH  rA  rE  replaceri  r   r.  statst_mtimer   fromtimestampr   r  r2   r3   r   r-   r   r   rb  r   )	ry   r   descklassrA   mtimer   dsr-   s	            r   rj   zSecureCourseFile.link  sP   $($4$4$'(8(8$9A$= DHMM 	!,,77Y??DNN$4[,FET??T^^%5		&Bt'7'7&8">?AT]]''(--/88,,8124[[)*VVHeR(II;B4zJLhhtxx(;(;TYYM~r   N)r   r   r   r   r   r   uploaded_byr   r   r   r>  	FileFieldr6  
private_fsr=  r   r   ACCESS_CHOICESrI  r   r   rz   rA  rE  rK  r   rb  r-   ri  rj   r   r   r   r8  r8    s   #&##$dfnnFK&&&&D9K6X@Dv,
KH"&""cDIKV&4&)+F (6''T>L(F((d$?M4
7   4 J J  r   r8  c                   H    e Zd Z ej                  eej                        Zy)r,  r   N)r   r   r   r   r   r   r   r   r   r   r   r,  r,    s    f6>>BGr   r,  c                      t         j                  j                  d      } d}t        j                  j                  | |      }t        j                  j                  |       }|j                  |d       y )Np064)r   i  )rv   r|   )rv   TR)r   )r   r   getr   rp   r   )r   yrr1  csites       r   testr    se    
..



0C	B##3R#8D""#".E	t,r   )8__doc__r   r-  zoneinfor   urllib.parserd  r2   pathlibr   	django.dbr   django.template.loaderr   markdownx.modelsr   	markdown2django.utils.safestringr   django.core.files.storager	   r   r   djphys.modelsr   r   r   djphys.funcsr   people.modelsr   MarkdownrC   r   r4   r   r>   r1   r7   r@   rE   PRIVATE_ROOTPRIVATE_URLrw  r!  rx  r&   rn   Modelrp   r   r   r6  r8  r,  r  r   r   r   <module>r     si    	   	   / +  - 7   6 6 " &  YI

	 DWW_&'
 3 3 "  "
-# 
-C 
-C 
- ""X-A-AC
  /# /C /Xy4 y4x
&,, 
8Nfll Nb(^v|| ^BC" C-r   