コード例 #1
0
ファイル: talk.py プロジェクト: alreadydone/seminars
 def ans(rmk):
     format = "%a %b %-d, %H:%M" if adapt_datetime(self.start_time, newtz=tz).year == datetime.now(tz).year else "%d-%b-%Y, %H:%M"
     return "%s-%s (%s)" % (
         adapt_datetime(start, newtz=newtz).strftime(format),
         adapt_datetime(end, newtz=newtz).strftime("%H:%M"),
         rmk,
     )
コード例 #2
0
ファイル: talk.py プロジェクト: tornaria/seminars
 def oneline(self,
             include_seminar=True,
             include_slides=False,
             include_video=False,
             include_subscribe=True,
             tz=None,
             _external=False):
     t, now, e = adapt_datetime(self.start_time, newtz=tz), adapt_datetime(
         datetime.now(), newtz=tz), adapt_datetime(self.end_time, newtz=tz)
     if t < now < e:
         datetime_tds = t.strftime(
             '<td class="weekday">%a</td><td class="monthdate">%b %d</td><td class="time"><b>%H:%M</b></td>'
         )
     else:
         datetime_tds = t.strftime(
             '<td class="weekday">%a</td><td class="monthdate">%b %d</td><td class="time">%H:%M</td>'
         )
     cols = []
     if include_seminar:
         cols.append(('class="seriesname"', self.show_seminar()))
     cols.append(('class="speaker"', self.show_speaker(affiliation=False)))
     cols.append(
         ('class="talktitle"', self.show_knowl_title(_external=_external)))
     if include_slides:
         cols.append(('', self.show_slides_link()))
     if include_video:
         cols.append(('', self.show_video_link()))
     if include_subscribe:
         cols.append(('class="subscribe"', self.show_subscribe()))
     #cols.append(('style="display: none;"', self.show_link_title()))
     return datetime_tds + "".join("<td %s>%s</td>" % c for c in cols)
コード例 #3
0
ファイル: talk.py プロジェクト: alreadydone/seminars
 def oneline(self, include_seminar=True, include_content=False, include_subscribe=True, tz=None, _external=False):
     rescheduled = self.rescheduled()
     t, now, e = adapt_datetime(self.start_time, newtz=tz), adapt_datetime(datetime.now(), newtz=tz), adapt_datetime(self.end_time, newtz=tz)
     if rescheduled:
         datetime_tds = t.strftime('<td class="weekday rescheduled">%a</i></td><td class="monthdate rescheduled">%b %d</td><td class="time rescheduled"><i>%H:%M</i></td>')
     else:
         if t < now < e:
             datetime_tds = t.strftime('<td class="weekday">%a</td><td class="monthdate">%b %d</td><td class="time"><b>%H:%M</b></td>')
         else:
             datetime_tds = t.strftime('<td class="weekday">%a</td><td class="monthdate">%b %d</td><td class="time">%H:%M</td>')
     cols = []
     rclass = " rescheduled" if rescheduled else ""
     if include_seminar:
         cols.append(('class="seriesname%s"'%rclass, self.show_seminar()))
     cols.append(('class="speaker%s"'%rclass, self.show_speaker(affiliation=False)))
     new_talk = talks_lookup(self.seminar_id, -self.seminar_ctr) if rescheduled else self
     cols.append(('class="talktitle"', new_talk.show_knowl_title(_external=_external, rescheduled=rescheduled, blackout=self.blackout_date(), tz=tz)))
     if include_content:
         cols.append(('', self.show_slides_link()))
         cols.append(('', self.show_video_link()))
         cols.append(('', self.show_paper_link()))
     if include_subscribe:
         if rescheduled:
             cols.append(("", ""))
         else:
             cols.append(('class="subscribe"', self.show_subscribe()))
     return datetime_tds + ''.join('<td %s>%s</td>' % c for c in cols)
コード例 #4
0
ファイル: talk.py プロジェクト: tornaria/seminars
 def ans(rmk):
     return "%s-%s (%s)" % (
         adapt_datetime(start,
                        newtz=newtz).strftime("%a %b %-d, %H:%M"),
         adapt_datetime(end, newtz=newtz).strftime("%H:%M"),
         rmk,
     )
コード例 #5
0
ファイル: talk.py プロジェクト: alreadydone/seminars
 def __init__(
     self,
     seminar_id=None,
     seminar_ctr=None,
     data=None,
     seminar=None,
     editing=False,
     include_deleted=False,
     include_pending=False,
 ):
     if data is None and not editing:
         data = talks_lookup(seminar_id, seminar_ctr, include_deleted=include_deleted, include_pending=include_pending)
         if data is None:
             raise ValueError("Talk %s/%s does not exist" % (seminar_id, seminar_ctr))
         data = dict(data.__dict__)
     elif data is not None:
         data = dict(data)
         # avoid Nones
         if data.get("topics") is None:
             data["topics"] = []
     if data and data.get("deleted"):
         include_deleted = True
     if seminar is None:
         seminar = WebSeminar(seminar_id, include_deleted=include_deleted)
     self.seminar = seminar
     self.new = data is None
     if self.new:
         self.seminar_id = seminar_id
         self.seminar_ctr = None
         self.token = secrets.token_hex(8)
         self.by_api = False # reset by API code if needed
         self.timezone = seminar.timezone
         self.deleted = False
         self.deleted_with_seminar = False
         self.hidden = False
         for key, typ in db.talks.col_type.items():
             if key == "id" or hasattr(self, key):
                 continue
             if key in inherited_talk_columns:
                 setattr(self, key, getattr(seminar, key))
             elif typ == "text":
                 setattr(self, key, "")
             elif typ == "text[]":
                 setattr(self, key, [])
             else:
                 # don't complain about columns we know are going to be set later
                 if not key in ["edited_by", "edited_at", "start_time", "end_time"]:
                     critical("Need to update talk code to account for schema change key=%s" % key)
                 setattr(self, key, None)
     else:
         # The output from psycopg2 seems to always be given in the server's time zone
         if data.get("timezone"):
             tz = pytz.timezone(data["timezone"])
             if data.get("start_time"):
                 data["start_time"] = adapt_datetime(data["start_time"], tz)
             if data.get("end_time"):
                 data["end_time"] = adapt_datetime(data["end_time"], tz)
         self.__dict__.update(data)
         self.cleanse()
コード例 #6
0
ファイル: talk.py プロジェクト: tornaria/seminars
 def show_date(self, tz=None):
     if self.start_time is None:
         return ""
     else:
         format = "%a %b %-d" if adapt_datetime(
             self.start_time,
             newtz=tz).year == datetime.now(tz).year else "%d-%b-%Y"
         return adapt_datetime(self.start_time, newtz=tz).strftime(format)
コード例 #7
0
ファイル: talk.py プロジェクト: AndrewVSutherland/seminars
    def event(self, user):
        link = url_for("show_talk",
                       seminar_id=self.seminar_id,
                       talkid=self.seminar_ctr,
                       _external=True,
                       _scheme='https')
        event = Event()
        #FIXME: code to remove hrefs from speaker name is a temporary hack to be
        # removed once we support multiple speakers
        if "href=" in self.speaker:
            tokens = re.split(r'>([a-zA-Z ]*)', self.speaker)
            speaker = ', '.join([
                tokens[i] for i in range(1, len(tokens), 2)
                if tokens[i].strip()
            ])
        else:
            speaker = self.show_speaker(raw=True)
        event.add("summary", speaker)
        event.add("dtstart", adapt_datetime(self.start_time, pytz.UTC))
        event.add("dtend", adapt_datetime(self.end_time, pytz.UTC))
        desc = ""
        # Title
        if self.title:
            desc += 'Title: <a href="%s">%s</a>\n' % (
                link,
                self.title,
            )
        # Speaker and seminar
        desc += "by %s" % (speaker)
        if self.seminar.name:
            desc += " as part of %s" % (self.seminar.name)
        desc += "\n\n"
        if self.live_link:
            link = self.show_live_link(user=user, raw=True)
            if link.startswith("http"):
                desc += "Interactive livestream: %s\n" % link
                if self.access_control == 2 and self.access_hint:
                    desc += "Password hint: %s\n" % self.access_hint
                event.add("url", link)
        if self.stream_link:
            link = self.show_stream_link(user=user, raw=True)
            if link.startswith("http"):
                desc += "View-only livestream: %s\n" % link
                event.add("url", link)
        if self.room:
            desc += "Lecture held in %s.\n" % self.room
        if self.abstract:
            desc += "\nAbstract\n%s\n" % self.abstract
        else:
            desc += "Abstract: TBA\n"
        if self.comments:
            desc += "\n%s\n" % self.comments

        event.add("description", desc)
        event.add("location", link)
        event.add("DTSTAMP", datetime.now(tz=pytz.UTC))
        event.add("UID", "%s/%s" % (self.seminar_id, self.seminar_ctr))
        return event
コード例 #8
0
 def __init__(
     self,
     semid=None,
     semctr=None,
     data=None,
     seminar=None,
     editing=False,
     showing=False,
     saving=False,
     deleted=False,
 ):
     if data is None and not editing:
         data = talks_lookup(semid, semctr, include_deleted=deleted)
         if data is None:
             raise ValueError("Talk %s/%s does not exist" % (semid, semctr))
         data = dict(data.__dict__)
     elif data is not None:
         data = dict(data)
         # avoid Nones
         if data.get("topics") is None:
             data["topics"] = []
     if seminar is None:
         seminar = WebSeminar(semid, deleted=deleted)
     self.seminar = seminar
     self.new = data is None
     self.deleted=False
     if self.new:
         self.seminar_id = semid
         self.seminar_ctr = None
         self.token = "%016x" % random.randrange(16 ** 16)
         self.display = seminar.display
         self.online = getattr(seminar, "online", bool(seminar.live_link))
         self.timezone = seminar.timezone
         for key, typ in db.talks.col_type.items():
             if key == "id" or hasattr(self, key):
                 continue
             elif db.seminars.col_type.get(key) == typ and getattr(seminar, key, None):
                 # carry over from seminar, but not comments
                 setattr(self, key, getattr(seminar, key) if key != "comments" else "")
             elif typ == "text":
                 setattr(self, key, "")
             elif typ == "text[]":
                 setattr(self, key, [])
             else:
                 critical("Need to update talk code to account for schema change key=%s" % key)
                 setattr(self, key, None)
     else:
         # The output from psycopg2 seems to always be given in the server's time zone
         if data.get("timezone"):
             tz = pytz.timezone(data["timezone"])
             if data.get("start_time"):
                 data["start_time"] = adapt_datetime(data["start_time"], tz)
             if data.get("end_time"):
                 data["end_time"] = adapt_datetime(data["end_time"], tz)
         # transition to topics including the subject
         if data.get("topics"):
             data["topics"] = [(topic if "_" in topic else "math_" + topic) for topic in data["topics"]]
         self.__dict__.update(data)
コード例 #9
0
ファイル: talk.py プロジェクト: alreadydone/seminars
    def show_end_time(self, tz=None):
        """
        INPUT:

        - ``tz`` -- a timezone object or None (use the current user's time zone)

        OUTPUT:

        If ``tz`` is given, the time in that time zone (no date).
        Otherwise, show the date only if different from the date of the start time in that time zone.
        """
        # This is used in show_time_and_duration, and needs to include the ending date if different (might not be the same in current user's time zone)
        t = adapt_datetime(self.end_time, newtz=tz)
        if tz is not None:
            return t.strftime("%H:%M")
        t0 = adapt_datetime(self.start_time, newtz=tz)
        if t0.date() == t.date():
            return t.strftime("%H:%M")
        else:
            return t.strftime("%a %b %-d, %H:%M")
コード例 #10
0
ファイル: talk.py プロジェクト: edgarcosta/seminars
    def event(self, user):
        event = Event()
        event.add("summary", self.speaker)
        event.add("dtstart", adapt_datetime(self.start_time, pytz.UTC))
        event.add("dtend", adapt_datetime(self.end_time, pytz.UTC))
        desc = ""
        # Title
        if self.title:
            desc += "Title: %s\n" % (self.title)
        # Speaker and seminar
        desc += "by %s" % (self.speaker)
        if self.speaker_affiliation:
            desc += " (%s)" % (self.speaker_affiliation)
        if self.seminar.name:
            desc += " as part of %s" % (self.seminar.name)
        desc += "\n\n"
        if self.live_link:
            link = self.show_live_link(user=user, raw=True)
            if link.startswith("http"):
                desc += "Access: %s\n" % (link)
                event.add("url", link)
        if self.room:
            desc += "Lecture held in %s.\n" % self.room
        if self.abstract:
            desc += "\nAbstract\n%s\n" % self.abstract
        else:
            desc += "Abstract: TBA\n"
        if self.comments:
            desc += "\n%s\n" % (self.comments)

        event.add("description", desc)
        if self.room:
            event.add("location", "Lecture held in {}".format(self.room))
        event.add("DTSTAMP", datetime.datetime.now(tz=pytz.UTC))
        event.add("UID", "%s/%s" % (self.seminar_id, self.seminar_ctr))
        return event
コード例 #11
0
 def oneline(
     self,
     conference=False,
     include_institutions=True,
     include_datetime=True,
     include_topics=False,
     include_audience=False,
     include_subscribe=True,
     show_attributes=False,
 ):
     datetime_tds = ""
     if include_datetime:
         if conference:  # include start and end date instead
             if self.is_conference and self.start_date and self.end_date:
                 if self.start_date == self.end_date:
                     datetime_tds = '<td colspan="2" class="onedate">' + self._show_date(
                         self.start_date) + '</td>'
                 else:
                     datetime_tds = '<td class="startdate">' + self._show_date(
                         self.start_date
                     ) + '</td><td class="enddate">' + self._show_date(
                         self.end_date) + '</td>'
             else:
                 datetime_tds = '<td class="startdate"></td><td class="enddate"></td>'
         else:  # could include both conferences and seminar series
             t = adapt_datetime(self.next_talk_time)
             if t is None:
                 datetime_tds = '<td></td><td></td><td></td>'
             else:
                 datetime_tds = t.strftime(
                     '<td class="weekday">%a</td><td class="monthdate">%b %d</td><td class="time">%H:%M</td>'
                 )
     cols = []
     cols.append(
         ('class="seriesname"',
          self.show_name(show_attributes=show_attributes,
                         homepage_link=True if self.deleted else False)))
     if include_institutions:
         cols.append(('class="institutions"', self.show_institutions()))
     if include_audience:
         cols.append(('class="audience"', self.show_audience()))
     if include_topics:
         cols.append(('class="topics"', self.show_topics()))
     if include_subscribe:
         cols.append(('class="subscribe"', self.show_subscribe()))
     return datetime_tds + "".join("<td %s>%s</td>" % c for c in cols)
コード例 #12
0
ファイル: seminar.py プロジェクト: akhayoon/seminars
 def oneline(
     self,
     conference=False,
     include_institutions=True,
     include_datetime=True,
     include_description=True,
     include_topics=False,
     include_subscribe=True,
     show_attributes=False,
 ):
     cols = []
     if include_datetime:
         if conference:  # include start and end date instead
             if self.start_date is None:
                 cols.append(('class="date"', ""))
             else:
                 cols.append(('class="date"',
                              self.start_date.strftime("%a %b %-d")))
             if self.end_date is None:
                 cols.append(('class="date"', ""))
             else:
                 cols.append(
                     ('class="date"', self.end_date.strftime("%a %b %-d")))
         else:  # could include both conferences and seminar series
             t = adapt_datetime(self.next_talk_time)
             if t is None:
                 cols.append(('class="date"', ""))
                 cols.append(('class="time"', ""))
             else:
                 cols.append(('class="date"', t.strftime("%a %b %-d")))
                 cols.append(('class="time"', t.strftime("%H:%M")))
     cols.append(
         ('class="name"', self.show_name(show_attributes=show_attributes)))
     if include_institutions:
         cols.append(('class="institution"', self.show_institutions()))
     if include_description:
         cols.append(('class="description"', self.show_description()))
     if include_topics:
         cols.append(('class="topics"', self.show_topics()))
     if include_subscribe:
         cols.append(('class="subscribe"', self.show_subscribe()))
     return "".join("<td %s>%s</td>" % c for c in cols)
コード例 #13
0
ファイル: seminar.py プロジェクト: tornaria/seminars
 def __init__(
     self, shortname, data=None, organizers=None, editing=False, showing=False, saving=False, deleted=False,  user=None,
 ):
     if user is None:
         user = current_user
     if data is None and not editing:
         data = seminars_lookup(shortname, include_deleted=deleted)
         if data is None:
             raise ValueError("Seminar %s does not exist" % shortname)
         data = dict(data.__dict__)
     elif data is not None:
         data = dict(data)
         if data.get("topics") is None:
             data["topics"] = []
         if data.get("institutions") is None:
             data["institutions"] = []
         if data.get("timezone") is None:
             data["timesone"] = str(user.tz)
     self.new = data is None
     self.deleted = False
     if self.new:
         self.shortname = shortname
         self.display = user.is_creator
         self.online = True  # default
         self.by_api = False # reset by API code if needed
         self.access = "open"  # default FIXME: remove once we switch to access_control
         self.access_control = 4 # default is instant registration
         self.access_time = None
         self.edited_by = user.id
         self.visibility = 2 # public by default, once display is set to True
         self.level = 0 # default is research seminar
         self.is_conference = False  # seminar by default
         self.frequency = 7
         self.per_day = 1
         self.weekday = self.start_time = self.end_time = None
         self.timezone = str(user.tz)
         for key, typ in db.seminars.col_type.items():
             if key == "id" or hasattr(self, key):
                 continue
             elif typ == "text":
                 setattr(self, key, "")
             elif typ == "text[]":
                 setattr(self, key, [])
             elif typ == "smallint[]":
                 setattr(self, key, [])
             elif typ == "timestamp with time zone":
                 setattr(self, key, None)
             elif typ == "timestamp with time zone[]":
                 setattr(self, key, [])
             elif typ == "date":
                 setattr(self, key, None)
             else:
                 critical(
                     "Need to update seminar code to account for schema change key=%s" % key
                 )
                 setattr(self, key, None)
         if organizers is None:
             organizers = [
                 {
                     "seminar_id": self.shortname,
                     "email": user.email,
                     "homepage": user.homepage,
                     "name": user.name,
                     "order": 0,
                     "curator": False,
                     "display": True,
                     "contact": True,
                 }
             ]
     else:
         # The output from psycopg2 seems to always be given in the server's time zone
         if data.get("timezone"):
             tz = pytz.timezone(data["timezone"])
             if data.get("start_time"):
                 data["start_time"] = adapt_datetime(data["start_time"], tz)
             if data.get("end_time"):
                 data["end_time"] = adapt_datetime(data["end_time"], tz)
         self.__dict__.update(data)
     if organizers is None:
         organizers = list(
             db.seminar_organizers.search({"seminar_id": self.shortname}, sort=["order"])
         )
     self.organizers = organizers
     self.cleanse()
コード例 #14
0
ファイル: seminar.py プロジェクト: akhayoon/seminars
 def __init__(self,
              shortname,
              data=None,
              organizer_data=None,
              editing=False,
              showing=False,
              saving=False,
              deleted=False):
     if data is None and not editing:
         data = seminars_lookup(shortname, include_deleted=deleted)
         if data is None:
             raise ValueError("Seminar %s does not exist" % shortname)
         data = dict(data.__dict__)
     elif data is not None:
         data = dict(data)
         if data.get("topics") is None:
             data["topics"] = []
         if data.get("institutions") is None:
             data["institutions"] = []
         if data.get("timezone") is None:
             data["timesone"] = str(current_user.tz)
     self.new = data is None
     self.deleted = False
     if self.new:
         self.shortname = shortname
         self.display = current_user.is_creator
         self.online = True  # default
         self.access = "open"  # default
         self.visibility = 2  # public by default, once display is set to True
         self.is_conference = False  # seminar by default
         self.frequency = 7
         self.per_day = 1
         self.weekday = self.start_time = self.end_time = None
         self.timezone = str(current_user.tz)
         for key, typ in db.seminars.col_type.items():
             if key == "id" or hasattr(self, key):
                 continue
             elif typ == "text":
                 setattr(self, key, "")
             elif typ == "text[]":
                 setattr(self, key, [])
             elif typ == "smallint[]":
                 setattr(self, key, [])
             elif typ == "timestamp with time zone":
                 setattr(self, key, None)
             elif typ == "timestamp with time zone[]":
                 setattr(self, key, [])
             elif typ == "date":
                 setattr(self, key, None)
             elif typ == "bigint":
                 setattr(self, key, None)
             else:
                 critical(
                     "Need to update seminar code to account for schema change key=%s"
                     % key)
                 setattr(self, key, None)
         if organizer_data is None:
             organizer_data = [{
                 "seminar_id": self.shortname,
                 "email": current_user.email,
                 "homepage": current_user.homepage,
                 "full_name": current_user.name,
                 "order": 0,
                 "curator": False,
                 "display": True,
                 "contact": True,
             }]
     else:
         # The output from psycopg2 seems to always be given in the server's time zone
         if data.get("timezone"):
             tz = pytz.timezone(data["timezone"])
             if data.get("start_time"):
                 data["start_time"] = adapt_datetime(data["start_time"], tz)
             if data.get("end_time"):
                 data["end_time"] = adapt_datetime(data["end_time"], tz)
         # transition to topics including the subject
         if data.get("topics"):
             data["topics"] = [(topic if "_" in topic else "math_" + topic)
                               for topic in data["topics"]]
         self.__dict__.update(data)
     if organizer_data is None:
         organizer_data = list(
             db.seminar_organizers.search({"seminar_id": self.shortname},
                                          sort=["order"]))
     self.organizer_data = organizer_data
     self.convert_time_to_times()
コード例 #15
0
ファイル: talk.py プロジェクト: alreadydone/seminars
 def blackout_date(self):
     return adapt_datetime(self.start_time, newtz=self.tz).strftime("%Y-%m-%d") in blackout_dates
コード例 #16
0
ファイル: talk.py プロジェクト: alreadydone/seminars
 def show_daytimes(self, tz=None):
     return adapt_datetime(self.start_time, tz).strftime("%H:%M") + "-" + adapt_datetime(self.end_time, tz).strftime("%H:%M")
コード例 #17
0
ファイル: talk.py プロジェクト: alreadydone/seminars
 def show_start_time(self, tz=None):
     return adapt_datetime(self.start_time, tz).strftime("%H:%M")
コード例 #18
0
ファイル: main.py プロジェクト: tornaria/seminars
def _talks_index(query={}, sort=None, subsection=None, past=False):
    # Eventually want some kind of cutoff on which talks are included.
    search_array = TalkSearchArray(past=past)
    info = to_dict(read_search_cookie(search_array), search_array=search_array)
    info.update(request.args)
    query = dict(query)
    parse_substring(info, query, "keywords",
                    ["title",
                     "abstract",
                     "speaker",
                     "speaker_affiliation",
                     "seminar_id",
                     "comments",
                     "speaker_homepage",
                     "paper_link"])
    more = {} # we will be selecting talks satsifying the query and recording whether they satisfy the "more" query
    # Note that talks_parser ignores the "time" field at the moment; see below for workaround
    talks_parser(info, more)
    if topdomain() == "mathseminars.org":
        query["topics"] = {"$contains": "math"}
    query["hidden"] = {"$or": [False, {"$exists": False}]}
    if past:
        query["end_time"] = {"$lt": datetime.now()}
        if sort is None:
            sort = [("start_time", -1), "seminar_id"]
    else:
        query["end_time"] = {"$gte": datetime.now()}
        if sort is None:
            sort = ["start_time", "seminar_id"]
    talks = list(talks_search(query, sort=sort, seminar_dict=all_seminars(), more=more))
    # Filtering on display and hidden isn't sufficient since the seminar could be private
    talks = [talk for talk in talks if talk.searchable()]
    # While we may be able to write a query specifying inequalities on the timestamp in the user's timezone, it's not easily supported by talks_search.  So we filter afterward
    timerange = info.get("timerange", "").strip()
    if timerange:
        tz = current_user.tz
        try:
            timerange = process_user_input(timerange, col="search", typ="daytimes")
        except ValueError:
            try:
                onetime = process_user_input(timerange, col="search", typ="daytime")
            except ValueError:
                flash_error("Invalid time range input: %s", timerange)
            else:
                for talk in talks:
                    if talk.more:
                        talkstart = adapt_datetime(talk.start_time, tz)
                        t = date_and_daytime_to_time(talkstart.date(), onetime, tz)
                        talk.more = (t == talkstart)
        else:
            for talk in talks:
                if talk.more:
                    talkstart = adapt_datetime(talk.start_time, tz)
                    talkend = adapt_datetime(talk.end_time, tz)
                    t0, t1 = date_and_daytimes_to_times(talkstart.date(), timerange, tz)
                    talk.more = (t0 <= talkstart) and (talkend <= t1)
    counters = _get_counters(talks)
    row_attributes = _get_row_attributes(talks)
    response = make_response(render_template(
        "browse_talks.html",
        title="Browse talks",
        section="Browse",
        info=info,
        subsection=subsection,
        talk_row_attributes=zip(talks, row_attributes),
        past=past,
        **counters
    ))
    if request.cookies.get("topics", ""):
        # TODO: when we move cookie data to server with ajax calls, this will need to get updated again
        # For now we set the max_age to 30 years
        response.set_cookie("topics_dict", topic_dag.port_cookie(), max_age=60*60*24*365*30)
        response.set_cookie("topics", "", max_age=0)
    return response
コード例 #19
0
def layout_schedule(seminar, data):
    """ Returns a list of schedule slots in specified date range (date, daytime-interval, talk)
        where talk is a WebTalk or none.  Picks default dates if none specified
    """
    tz = seminar.tz

    def parse_date(key):
        date = data.get(key)
        if date:
            try:
                return process_user_input(date, "date", "date", tz)
            except ValueError:
                flash_warning(
                    "Invalid date %s ignored, please use a format like mmm dd, yyyy or dd-mmm-yyyy or mm/dd/yyyy",
                    date)

    def slot_start_time(s):
        # put slots with no time specified at the end of the day
        return date_and_daytimes_to_times(parse_time(s[0]),
                                          s[1] if s[1] else "23:59-23:59",
                                          tz)[0]

    begin = parse_date("begin")
    end = parse_date("end")
    shortname = seminar.shortname
    now = datetime.now(tz=tz)
    today = now.date()
    day = timedelta(days=1)
    if seminar.is_conference and (seminar.start_date is None
                                  or seminar.end_date is None):
        flash_warning(
            "You have not specified the start and end dates of your conference (we chose a date range to layout your schedule)."
        )
    begin = seminar.start_date if begin is None and seminar.is_conference else begin
    begin = today if begin is None else begin
    end = seminar.end_date if end is None and seminar.is_conference else end
    if end is None:
        if seminar.is_conference:
            if seminar.per_day:
                end = begin + day * ceil(SCHEDULE_LEN / seminar.per_day)
            else:
                end = begin + 7 * day
        else:
            if seminar.frequency:
                end = begin + day * ceil(
                    SCHEDULE_LEN * seminar.frequency / len(seminar.time_slots))
            else:
                end = begin + 14 * day
    if end < begin:
        end = begin
    data["begin"] = seminar.show_input_date(begin)
    data["end"] = seminar.show_input_date(end)
    midnight_begin = midnight(begin, tz)
    midnight_end = midnight(end, tz)
    query = {"$gte": midnight_begin, "$lt": midnight_end + day}
    talks = list(
        talks_search({
            "seminar_id": shortname,
            "start_time": query
        },
                     sort=["start_time"]))
    slots = [(t.show_date(tz), t.show_daytimes(tz), t) for t in talks]
    if seminar.is_conference:
        newslots = []
        d = midnight_begin
        while d < midnight_end + day:
            newslots += [(seminar.show_schedule_date(d), "", None)
                         for i in range(seminar.per_day)]
            d += day
        for t in slots:
            if (t[0], "", None) in newslots:
                newslots.remove((t[0], "", None))
        slots = sorted(slots + newslots, key=lambda t: slot_start_time(t))
        return slots
    if not seminar.frequency:
        for i in range(max(SCHEDULE_LEN - len(slots), 3)):
            slots.append(("", "", None))
    else:
        # figure out week to start in.
        # use the week of the first seminar after begin if any, otherwise last seminar before begin, if any
        # otherwise just use the week containing begin
        t = talks_lucky(
            {
                "seminar_id": shortname,
                "start_time": {
                    "$gte": midnight_begin
                }
            },
            sort=[("start_time", 1)])
        if not t:
            t = talks_lucky(
                {
                    "seminar_id": shortname,
                    "start_time": {
                        "$lt": midnight_begin
                    }
                },
                sort=[("start_time", -1)])
        if t:
            t = adapt_datetime(t.start_time, newtz=tz)
            w = t - t.weekday() * day
            while w > midnight_begin:
                w -= day * seminar.frequency
            while w + day * seminar.frequency < midnight_begin:
                w += day * seminar.frequency
        else:
            w = midnight_begin - midnight_begin.weekday() * day
        # make a list of all seminar time slots in [begin,end)
        newslots = []
        while w < midnight_end:
            for i in range(len(seminar.weekdays)):
                d = w + day * seminar.weekdays[i]
                if d >= midnight_begin and d < midnight_end + day:
                    newslots.append((seminar.show_schedule_date(d),
                                     seminar.time_slots[i], None))
            w = w + day * seminar.frequency
        # remove slots that are (exactly) matched by an existing talk
        # this should handle slots that occur with multiplicity
        for t in slots:
            if (t[0], t[1], None) in newslots:
                newslots.remove((t[0], t[1], None))
        slots = sorted(slots + newslots, key=lambda t: slot_start_time(t))
    return slots
コード例 #20
0
ファイル: talk.py プロジェクト: tornaria/seminars
 def __init__(
     self,
     seminar_id=None,
     seminar_ctr=None,
     data=None,
     seminar=None,
     editing=False,
     showing=False,
     saving=False,
     deleted=False,
 ):
     if data is None and not editing:
         data = talks_lookup(seminar_id,
                             seminar_ctr,
                             include_deleted=deleted)
         if data is None:
             raise ValueError("Talk %s/%s does not exist" %
                              (seminar_id, seminar_ctr))
         data = dict(data.__dict__)
     elif data is not None:
         data = dict(data)
         # avoid Nones
         if data.get("topics") is None:
             data["topics"] = []
     if data and data.get("deleted"):
         deleted = True
     if seminar is None:
         seminar = WebSeminar(seminar_id, deleted=deleted)
     self.seminar = seminar
     self.new = data is None
     self.deleted = False
     if self.new:
         self.seminar_id = seminar_id
         self.seminar_ctr = None
         self.token = secrets.token_hex(8)
         self.display = seminar.display
         self.online = getattr(seminar, "online", bool(seminar.live_link))
         self.by_api = False  # reset by API code if needed
         self.timezone = seminar.timezone
         for key, typ in db.talks.col_type.items():
             if key == "id" or hasattr(self, key):
                 continue
             elif db.seminars.col_type.get(key) == typ and getattr(
                     seminar, key, None):
                 # carry over from seminar, but not comments
                 setattr(self, key,
                         getattr(seminar, key) if key != "comments" else "")
                 print("talk inherited %s = %s from seminar" %
                       (key, getattr(self, key)))
             elif typ == "text":
                 setattr(self, key, "")
             elif typ == "text[]":
                 setattr(self, key, [])
             else:
                 critical(
                     "Need to update talk code to account for schema change key=%s"
                     % key)
                 setattr(self, key, None)
     else:
         # The output from psycopg2 seems to always be given in the server's time zone
         if data.get("timezone"):
             tz = pytz.timezone(data["timezone"])
             if data.get("start_time"):
                 data["start_time"] = adapt_datetime(data["start_time"], tz)
             if data.get("end_time"):
                 data["end_time"] = adapt_datetime(data["end_time"], tz)
         self.__dict__.update(data)
     self.cleanse()
コード例 #21
0
 def __init__(self,
              shortname,
              data=None,
              organizer_data=None,
              editing=False,
              showing=False,
              saving=False):
     if data is None and not editing:
         data = seminars_lookup(shortname)
         if data is None:
             raise ValueError("Seminar %s does not exist" % shortname)
         data = dict(data.__dict__)
     elif data is not None:
         data = dict(data)
         if data.get("topics") is None:
             data["topics"] = []
         if data.get("instructions") is None:
             data["instructions"] = []
     self.new = data is None
     if self.new:
         self.shortname = shortname
         self.display = current_user.is_creator
         self.online = True  # default
         self.access = "open"  # default
         self.archived = False  # don't start out archived
         self.is_conference = False  # seminar by default
         self.frequency = 7
         self.per_day = 1
         self.weekday = self.start_time = self.end_time = None
         self.timezone = str(current_user.tz)
         self.start_date = None
         self.end_date = None
         for key, typ in db.seminars.col_type.items():
             if key == "id" or hasattr(self, key):
                 continue
             elif typ == "text":
                 setattr(self, key, "")
             elif typ == "text[]":
                 setattr(self, key, [])
             else:
                 raise ValueError(
                     "Need to update seminar code to account for schema change"
                 )
         if organizer_data is None:
             organizer_data = [{
                 "seminar_id": self.shortname,
                 "email": current_user.email,
                 "full_name": current_user.name,
                 "order": 0,
                 "curator": False,
                 "display": True,
                 "contact": True,
             }]
     else:
         # The output from psycopg2 seems to always be given in the server's time zone
         if data.get("timezone"):
             tz = pytz.timezone(data["timezone"])
             if data.get("start_time"):
                 data["start_time"] = adapt_datetime(data["start_time"], tz)
             if data.get("end_time"):
                 data["end_time"] = adapt_datetime(data["end_time"], tz)
         self.__dict__.update(data)
     if organizer_data is None:
         organizer_data = list(
             db.seminar_organizers.search({"seminar_id": self.shortname},
                                          sort=["order"]))
     self.organizer_data = organizer_data
コード例 #22
0
ファイル: talk.py プロジェクト: edgarcosta/seminars
 def show_date(self):
     if self.start_time is None:
         return ""
     else:
         return adapt_datetime(self.start_time).strftime("%a %b %-d")
コード例 #23
0
 def show_schedule_date(self, date):
     if not date:
         return ""
     format = "%a %b %-d" if adapt_datetime(
         date, self.tz).year == datetime.now(self.tz).year else "%d-%b-%Y"
     return adapt_datetime(date, self.tz).strftime(format)
コード例 #24
0
def _talks_index(
    query={},
    sort=None,
    subsection=None,
    past=False,
    keywords="",
    limit=None,  # this is an upper bound on desired number of talks, we might filter some extra out
    limitbuffer=1000,  # the number of extra talks that we give ourselves to try to get the limit right
    asblock=False,  # the number of talks returned is based on star time blocks
    getcounters=True,  # doesn't limit the SQL search to get the full counters
    visible_counter=0,
    fully_filtered=True,
):
    # Eventually want some kind of cutoff on which talks are included.
    search_array = TalkSearchArray(past=past)
    info = to_dict(read_search_cookie(search_array), search_array=search_array)
    info.update(request.args)
    if keywords:
        info["keywords"] = keywords
    keywords = info.get("keywords", "")
    query = dict(query)
    parse_substring(info, query, "keywords", [
        "title", "abstract", "speaker", "speaker_affiliation", "seminar_id",
        "comments", "speaker_homepage", "paper_link"
    ])
    more = {
    }  # we will be selecting talks satsifying the query and recording whether they satisfy the "more" query
    # Note that talks_parser ignores the "time" field at the moment; see below for workaround
    talks_parser(info, more)
    if topdomain() == "mathseminars.org":
        query["topics"] = {"$contains": "math"}
    query["display"] = True
    query["hidden"] = {"$or": [False, {"$exists": False}]}
    query["audience"] = {"$lte": DEFAULT_AUDIENCE}
    now = datetime.now(pytz.UTC)
    if past:
        query["end_time"] = {"$lt": now}
        query["seminar_ctr"] = {"$gt": 0}  # don't show rescheduled talks
        if sort is None:
            sort = [("start_time", -1), "seminar_id"]
    else:
        query["end_time"] = {"$gte": now}
        if sort is None:
            sort = ["start_time", "seminar_id"]

    def dosearch(limit=limit, limitbuffer=limitbuffer):
        if limit and not getcounters:
            # we fetch extra talks to account for filtering
            talks = talks_search(query,
                                 sort=sort,
                                 seminar_dict=all_seminars(),
                                 more=more,
                                 limit=limit + limitbuffer)
        else:
            talks = talks_search(query,
                                 sort=sort,
                                 seminar_dict=all_seminars(),
                                 more=more)
        # Filtering on display and hidden isn't sufficient since the seminar could be private
        talks = [talk for talk in talks if talk.searchable()]
        return talks

    def truncateasblock(talks, retry=True):
        if not talks:
            return talks
        last_time = None
        # find enough talks such that the next talk has a different starting time
        for i, t in enumerate(talks):
            if last_time is None:
                last_time = t.start_time
                continue
            if t.start_time != last_time:
                if i > limit:
                    return talks[:i - 1]
                else:
                    last_time = t.start_time
        else:
            if retry and limit and not getcounters:
                # redo the search without limits
                talks = dosearch(limit=None)
                return truncateasblock(talks, retry=False)
            return talks

    def truncate(talks):
        if asblock and limit:
            return truncateasblock(talks)
        elif limit:
            return talks[:limit]
        else:
            return talks

    talks = dosearch()
    if getcounters:
        counters = _get_counters(talks)
    else:
        counters = _get_counters([])

    if getcounters and fully_filtered:
        # the initial query was not limited as getcounters = True
        # we will first filter after figuring out the more attribute
        # and then truncate
        pass
    else:
        # we are not going to filter or the query was already limited, so we can truncate
        talks = truncate(talks)
    # While we may be able to write a query specifying inequalities on the timestamp in the user's timezone, it's not easily supported by talks_search.  So we filter afterward
    timerange = info.get("timerange", "").strip()
    if timerange:
        tz = current_user.tz
        try:
            timerange = process_user_input(timerange,
                                           col="search",
                                           typ="daytimes")
        except ValueError:
            try:
                onetime = process_user_input(timerange,
                                             col="search",
                                             typ="daytime")
            except ValueError:
                flash_error("Invalid time range input: %s", timerange)
            else:
                for talk in talks:
                    if talk.more:
                        talkstart = adapt_datetime(talk.start_time, tz)
                        t = date_and_daytime_to_time(talkstart.date(), onetime,
                                                     tz)
                        talk.more = (t == talkstart)
        else:
            for talk in talks:
                if talk.more:
                    talkstart = adapt_datetime(talk.start_time, tz)
                    talkend = adapt_datetime(talk.end_time, tz)
                    t0, t1 = date_and_daytimes_to_times(
                        talkstart.date(), timerange, tz)
                    talk.more = (t0 <= talkstart) and (talkend <= t1)

    # get last_time before potential filtering
    last_time = int(talks[-1].start_time.timestamp()) if talks else None
    if fully_filtered:  # first filter then truncate
        row_attributes, talks = _get_row_attributes(talks, visible_counter,
                                                    fully_filtered)
        if getcounters:  # we have not yet truncated the results
            if limit and len(talks) > limit:
                talks = truncate(talks)
                row_attributes = row_attributes[:len(talks)]
                last_time = int(
                    talks[-1].start_time.timestamp()) if talks else None
    else:
        row_attributes = _get_row_attributes(talks, visible_counter)

    response = make_response(
        render_template("browse_talks.html",
                        title="Browse past talks" if past else "Browse talks",
                        section="Browse",
                        info=info,
                        subsection=subsection,
                        talk_row_attributes=zip(talks, row_attributes),
                        past=past,
                        last_time=last_time,
                        extraargs=urlencode({'keywords': keywords}),
                        **counters))
    if request.cookies.get("topics", ""):
        # TODO: when we move cookie data to server with ajax calls, this will need to get updated again
        # For now we set the max_age to 30 years
        response.set_cookie("topics_dict",
                            topic_dag.port_cookie(),
                            max_age=60 * 60 * 24 * 365 * 30)
        response.set_cookie("topics", "", max_age=0)

    # disable cache
    response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
    response.headers['Pragma'] = 'no-cache'
    return response
コード例 #25
0
def make_date_data(seminar, data):
    tz = seminar.tz

    def parse_date(key):
        date = data.get(key)
        if date:
            try:
                return process_user_input(date, "date", tz)
            except ValueError:
                pass

    begin = parse_date("begin")
    end = parse_date("end")
    frequency = data.get("frequency")
    try:
        frequency = int(frequency)
    except Exception:
        frequency = None
    if not frequency or frequency < 0:
        frequency = seminar.frequency
        if not frequency or frequency < 0:
            frequency = 1 if seminar.is_conference else 7
    try:
        weekday = short_weekdays.index(data.get("weekday", "")[:3])
    except ValueError:
        weekday = None
    if weekday is None:
        weekday = seminar.weekday
    shortname = seminar.shortname
    day = datetime.timedelta(days=1)
    now = datetime.datetime.now(tz=tz)
    today = now.date()
    midnight_today = now.replace(hour=0, minute=0, second=0, microsecond=0)
    if begin is None or seminar.start_time is None or seminar.end_time is None:
        future_talk = talks_lucky(
            {
                "seminar_id": shortname,
                "start_time": {
                    "$exists": True,
                    "$gte": midnight_today
                }
            },
            sort=["start_time"])
        last_talk = talks_lucky(
            {
                "seminar_id": shortname,
                "start_time": {
                    "$exists": True,
                    "$lt": midnight_today
                }
            },
            sort=[("start_time", -1)],
        )

    if begin is None:
        if seminar.is_conference:
            if seminar.start_date:
                begin = seminar.start_date
            else:
                begin = today
        else:
            if weekday is not None and frequency == 7:
                begin = today
                # Will set to next weekday below
            else:
                # Try to figure out a plan from future and past talks
                if future_talk is None:
                    if last_talk is None:
                        # Give up
                        begin = today
                    else:
                        begin = last_talk.start_time.date()
                        while begin < today:
                            begin += frequency * day
                else:
                    begin = future_talk.start_time.date()
                    while begin >= today:
                        begin -= frequency * day
                    begin += frequency * day
    if not seminar.is_conference and seminar.weekday is not None:
        # Weekly meetings: take the next one
        while begin.weekday() != weekday:
            begin += day
    if end is None:
        if seminar.is_conference:
            if seminar.end_date:
                end = seminar.end_date
                schedule_len = int((end - begin) / (frequency * day)) + 1
            else:
                end = begin + 6 * day
                schedule_len = 7
        else:
            end = begin + (SCHEDULE_LEN - 1) * frequency * day
            schedule_len = SCHEDULE_LEN
    else:
        schedule_len = abs(int((end - begin) / (frequency * day))) + 1
    seminar.frequency = frequency
    data["begin"] = seminar.show_input_date(begin)
    data["end"] = seminar.show_input_date(end)
    midnight_begin = localize_time(
        datetime.datetime.combine(begin, datetime.time()), tz)
    midnight_end = localize_time(
        datetime.datetime.combine(end, datetime.time()), tz)
    # add a day since we want to allow talks on the final day
    if end < begin:
        # Only possible by user input
        frequency = -frequency
        query = {"$gte": midnight_end, "$lt": midnight_begin + day}
    else:
        query = {"$gte": midnight_begin, "$lt": midnight_end + day}
    schedule_days = [begin + i * frequency * day for i in range(schedule_len)]
    scheduled_talks = list(
        talks_search({
            "seminar_id": shortname,
            "start_time": query
        }))
    by_date = defaultdict(list)
    for T in scheduled_talks:
        by_date[adapt_datetime(T.start_time, tz).date()].append(T)
    all_dates = sorted(set(schedule_days + list(by_date)),
                       reverse=(end < begin))
    # Fill in by_date with Nones up to the per_day value
    for date in all_dates:
        by_date[date].extend([None] * (seminar.per_day - len(by_date[date])))
    if seminar.start_time is None:
        if future_talk is not None and future_talk.start_time:
            seminar.start_time = future_talk.start_time.time()
        elif last_talk is not None and last_talk.start_time:
            seminar.start_time = last_talk.start_time.time()
    if seminar.end_time is None:
        if future_talk is not None and future_talk.start_time:
            seminar.end_time = future_talk.end_time.time()
        elif last_talk is not None and last_talk.start_time:
            seminar.end_time = last_talk.end_time.time()
    return seminar, all_dates, by_date