Jump to content

Widget:UPDEvents: Difference between revisions

From Iskomunidad
No edit summary
No edit summary
Line 1: Line 1:
<includeonly>
<includeonly>
<div id="upd-events-widget">
<div id="upd-events-widget">
   <div class="upd-events-loading">Loading upcoming events...</div>
   <div class="upd-events-loading">
    Loading upcoming events...
  </div>
   <ul class="upd-events-list" style="display:none;"></ul>
   <ul class="upd-events-list" style="display:none;"></ul>
</div>
</div>
Line 14: Line 16:
   var list = container.querySelector('.upd-events-list');
   var list = container.querySelector('.upd-events-list');


   var feedUrl = 'https://upd.edu.ph/events-list/?ical=1';
   var pageUrl = 'https://upd.edu.ph/events-list/';


   function decodeICS(value) {
   function showError() {
     return value
     loading.textContent =
       .replace(/\\n/gi, '\n')
       'Unable to load events automatically. ';
      .replace(/\\,/g, ',')
 
      .replace(/\\;/g, ';')
    var link = document.createElement('a');
      .replace(/\\\\/g, '\\');
    link.href = pageUrl;
    link.textContent = 'View all UP Diliman events';
    link.target = '_blank';
    link.rel = 'noopener noreferrer';
    loading.appendChild(link);
   }
   }


   function parseDate(value) {
   function cleanTitle(text) {
     if (!value) return null;
    return text
      .replace(/\s+/g, ' ')
      .replace(/\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]*\s+\d{1,2}\s*\|[\s\S]*$/i, '')
      .trim();
  }
 
  function getEventDate(text) {
    var match = text.match(
      /\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]*\s+(\d{1,2})\b/i
    );
 
     if (!match) return null;
 
    var months = {
      jan:0, feb:1, mar:2, apr:3, may:4, jun:5,
      jul:6, aug:7, sep:8, oct:9, nov:10, dec:11
    };


     // All-day event: DTSTART;VALUE=DATE:20261106
     var month = months[match[1].slice(0,3).toLowerCase()];
    if (/^\d{8}$/.test(value)) {
    var day = Number(match[2]);
      return new Date(
    var now = new Date();
        Date.UTC(
    var year = now.getFullYear();
          Number(value.slice(0, 4)),
          Number(value.slice(4, 6)) - 1,
          Number(value.slice(6, 8))
        )
      );
    }


     // UTC date-time ending in Z
     var date = new Date(year, month, day, 23, 59, 59);
    if (/^\d{8}T\d{6}Z$/.test(value)) {
      return new Date(
        value.slice(0, 4) + '-' +
        value.slice(4, 6) + '-' +
        value.slice(6, 8) + 'T' +
        value.slice(9, 11) + ':' +
        value.slice(11, 13) + ':' +
        value.slice(13, 15) + 'Z'
      );
    }


     // Date-time without Z: interpret as Philippine local time
     // Handle events listed around the New Year.
     if (/^\d{8}T\d{6}$/.test(value)) {
     if (date < now && now.getMonth() === 11 && month === 0) {
       return new Date(
       date.setFullYear(year + 1);
        value.slice(0, 4) + '-' +
    } else if (date < now && now.getMonth() === 0 && month === 11) {
        value.slice(4, 6) + '-' +
       return null;
        value.slice(6, 8) + 'T' +
        value.slice(9, 11) + ':' +
        value.slice(11, 13) + ':' +
        value.slice(13, 15) + '+08:00'
       );
     }
     }


     return null;
     return date;
   }
   }


  function showError() {
   fetch(pageUrl)
    loading.textContent =
      'Upcoming events could not be loaded. Please visit the UP Diliman Events page.';
    var link = document.createElement('a');
    link.href = 'https://upd.edu.ph/events-list/';
    link.textContent = ' View all events';
    link.target = '_blank';
    link.rel = 'noopener noreferrer';
    loading.appendChild(link);
  }
 
   fetch(feedUrl)
     .then(function (response) {
     .then(function (response) {
       if (!response.ok) throw new Error('Calendar feed unavailable');
       if (!response.ok) throw new Error('Could not retrieve event page');
       return response.text();
       return response.text();
     })
     })
     .then(function (ics) {
     .then(function (html) {
       // Join folded iCalendar lines.
       var doc = new DOMParser().parseFromString(html, 'text/html');
      ics = ics.replace(/\r?\n[ \t]/g, '');
       var anchors = doc.querySelectorAll('a[href]');
 
       var blocks = ics.match(/BEGIN:VEVENT[\s\S]*?END:VEVENT/g) || [];
      var now = new Date();
       var events = [];
       var events = [];
       var seen = {};
       var seen = {};


       blocks.forEach(function (block) {
       anchors.forEach(function (anchor) {
         var startMatch = block.match(/^DTSTART(?:;[^:]*)?:(.+)$/m);
         var url = new URL(anchor.getAttribute('href'), pageUrl);
         var titleMatch = block.match(/^SUMMARY(?:;[^:]*)?:(.+)$/m);
         if (url.hostname !== 'upd.edu.ph') return;
         var urlMatch = block.match(/^URL(?:;[^:]*)?:(.+)$/m);
         if (!/^\/events\/[^/]+\/?$/.test(url.pathname)) return;


         if (!startMatch || !titleMatch || !urlMatch) return;
         var rawText = (anchor.textContent || '')
          .replace(/\s+/g, ' ')
          .trim();


         var start = parseDate(startMatch[1].trim());
         var date = getEventDate(rawText);
         var title = decodeICS(titleMatch[1].trim());
         var title = cleanTitle(rawText);
        var url = urlMatch[1].trim();


         if (!start || start <= now) return;
         if (!date || date < new Date() || !title) return;
        if (!/^https:\/\/upd\.edu\.ph\/events\//i.test(url)) return;


        // Keep only the nearest upcoming occurrence of each event page.
         var key = url.href;
         var key = url + '|' + title.toLowerCase();
         if (seen[key]) return;
         if (seen[key]) return;
         seen[key] = true;
         seen[key] = true;
Line 111: Line 97:
         events.push({
         events.push({
           title: title,
           title: title,
           url: url,
           url: url.href,
           start: start
           date: date
         });
         });
       });
       });


       events.sort(function (a, b) {
       events.sort(function (a, b) {
         return a.start - b.start;
         return a.date - b.date;
       });
       });


Line 123: Line 109:


       if (!events.length) {
       if (!events.length) {
         loading.textContent = 'There are no upcoming events at this time.';
         loading.textContent =
          'No upcoming events were found.';
         return;
         return;
       }
       }
Line 144: Line 131:
     })
     })
     .catch(function (error) {
     .catch(function (error) {
       console.error('UP Diliman Events widget:', error);
       console.error('UPEvents widget:', error);
       showError();
       showError();
     });
     });

Revision as of 02:00, 29 October 2026