From 04bf9893eefc9b5d9e588b9fe4baee739b28e8a5 Mon Sep 17 00:00:00 2001 From: CHUN YU YAO Date: Mon, 1 Jan 2024 23:58:30 +0800 Subject: [PATCH] 2023-12-20 --- chrome_tixcraft.py | 2 +- config_launcher.py | 2 +- settings.py | 2 +- text_server.py | 2 +- webdriver/Maxbot_1.0.0/background.js | 9 +- .../Maxbot_1.0.0/js/cityline_event_common.js | 460 ++++++++++++++++++ .../Maxbot_1.0.0/js/cityline_event_detail.js | 309 ++++++++++++ webdriver/Maxbot_1.0.0/js/tixcraft_area.js | 96 +++- webdriver/Maxbot_1.0.0/js/tixcraft_detail.js | 10 + webdriver/Maxbot_1.0.0/js/tixcraft_game.js | 85 +++- webdriver/Maxbot_1.0.0/js/tixcraft_home.js | 2 + webdriver/Maxbot_1.0.0/js/tixcraft_ticket.js | 25 +- webdriver/Maxbot_1.0.0/manifest.json | 24 +- webdriver/Maxbot_1.0.0/rules_1.json | 245 ++++++++++ 14 files changed, 1254 insertions(+), 19 deletions(-) create mode 100644 webdriver/Maxbot_1.0.0/js/cityline_event_common.js create mode 100644 webdriver/Maxbot_1.0.0/js/cityline_event_detail.js create mode 100644 webdriver/Maxbot_1.0.0/js/tixcraft_detail.js create mode 100644 webdriver/Maxbot_1.0.0/rules_1.json diff --git a/chrome_tixcraft.py b/chrome_tixcraft.py index a4cd258..e8ffa94 100644 --- a/chrome_tixcraft.py +++ b/chrome_tixcraft.py @@ -54,7 +54,7 @@ import webbrowser import chromedriver_autoinstaller -CONST_APP_VERSION = "MaxBot (2023.12.19)" +CONST_APP_VERSION = "MaxBot (2023.12.20)" CONST_MAXBOT_CONFIG_FILE = "settings.json" CONST_MAXBOT_LAST_URL_FILE = "MAXBOT_LAST_URL.txt" diff --git a/config_launcher.py b/config_launcher.py index 7f19f8b..d69bcfd 100644 --- a/config_launcher.py +++ b/config_launcher.py @@ -22,7 +22,7 @@ import sys import threading import webbrowser -CONST_APP_VERSION = "MaxBot (2023.12.19)" +CONST_APP_VERSION = "MaxBot (2023.12.20)" CONST_MAXBOT_LAUNCHER_FILE = "config_launcher.json" CONST_MAXBOT_CONFIG_FILE = "settings.json" diff --git a/settings.py b/settings.py index 672e608..317d9c0 100644 --- a/settings.py +++ b/settings.py @@ -34,7 +34,7 @@ import ssl ssl._create_default_https_context = ssl._create_unverified_context -CONST_APP_VERSION = "MaxBot (2023.12.19)" +CONST_APP_VERSION = "MaxBot (2023.12.20)" CONST_MAXBOT_CONFIG_FILE = "settings.json" CONST_MAXBOT_LAST_URL_FILE = "MAXBOT_LAST_URL.txt" diff --git a/text_server.py b/text_server.py index 34b1857..60daca8 100644 --- a/text_server.py +++ b/text_server.py @@ -27,7 +27,7 @@ import pyperclip import tornado from tornado.web import Application -CONST_APP_VERSION = "MaxBot (2023.12.19)" +CONST_APP_VERSION = "MaxBot (2023.12.20)" CONST_MAXBOT_QUESTION_FILE = "MAXBOT_QUESTION.txt" diff --git a/webdriver/Maxbot_1.0.0/background.js b/webdriver/Maxbot_1.0.0/background.js index bdf19df..c32eb43 100644 --- a/webdriver/Maxbot_1.0.0/background.js +++ b/webdriver/Maxbot_1.0.0/background.js @@ -1,3 +1,10 @@ +'use strict'; + +chrome.declarativeNetRequest.onRuleMatchedDebug.addListener((e) => { + const msg = `Navigation blocked to ${e.request.url} on tab ${e.request.tabId}.`; + //console.log(msg); +}); + chrome.runtime.onInstalled.addListener(function(){ fetch("data/settings.json") .then((resp) => resp.json()) @@ -10,4 +17,4 @@ chrome.runtime.onInstalled.addListener(function(){ ); } ); -}); \ No newline at end of file +}); diff --git a/webdriver/Maxbot_1.0.0/js/cityline_event_common.js b/webdriver/Maxbot_1.0.0/js/cityline_event_common.js new file mode 100644 index 0000000..c4263a9 --- /dev/null +++ b/webdriver/Maxbot_1.0.0/js/cityline_event_common.js @@ -0,0 +1,460 @@ +var getUrlParameter = function getUrlParameter(sParam) { + var sPageURL = window.location.search.substring(1), + sURLVariables = sPageURL.split('&'), + sParameterName, + i; + + for (i = 0; i < sURLVariables.length; i++) { + sParameterName = sURLVariables[i].split('='); + + if (sParameterName[0] === sParam) { + return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]); + } + } + return false; +}; + +var getI18nMonthYear = function(date) { + let year = date.year; + let month = date.month - 1; + let monthTitles = ['month-title-jan', 'month-title-feb', 'month-title-mar', 'month-title-apr', 'month-title-may', 'month-title-jun', 'month-title-jul', 'month-title-aug', 'month-title-sep', 'month-title-oct', 'month-title-Nov', 'month-title-Dec']; + let monthTitle = monthTitles[month]; + let comma = $.i18n().locale == 'en' ? "," : ","; + return $.i18n(monthTitle) + comma + " " + year; +} + +var getI18nWeek = function(date) { + let weekDayTitles = ['week-title-sun', 'week-title-mon', 'week-title-tue', 'week-title-wed', 'week-title-thu', 'week-title-fri', 'week-title-sat']; + let day = date.weekday%7; + let weekDayTitle = weekDayTitles[day]; + return $.i18n(weekDayTitle); +} + +var getI18nTime = function(date) { + let i18nWeek = getI18nWeek(date); + let hour = date.hour; + let hourTitle = (hour < 10) ? "0" + hour : hour; + let minute = date.minute; + let minuteTitle = (minute < 10) ? "0" + minute : minute; + let comma = $.i18n().locale == 'en' ? "," : ","; + return i18nWeek + comma + " " + hourTitle + ":" + minuteTitle; +} + +var getI18nSrDate = function(date) { + let day = date.day; + let month = date.month - 1; + let year = date.year; + let monthTitles = ['month-title-jan', 'month-title-feb', 'month-title-mar', 'month-title-apr', 'month-title-may', 'month-title-jun', 'month-title-jul', 'month-title-aug', 'month-title-sep', 'month-title-oct', 'month-title-Nov', 'month-title-Dec']; + let monthTitle = $.i18n().locale == 'en' ? $.i18n(monthTitles[month]) : month + 1; + return $.i18n('sr-date-format', day, monthTitle, year); // $1=Day, $2=Month, $3=Year +} + +var getPerfHtml = function(perf) { + let status = perf.status; + let statusTitles = {"AVAILABLE" : null, "LIMIT" : "status-title-limit", "SOLDOUT" : "status-title-soldout"}; + let statusTitle = statusTitles[status]; + let statusValue = statusTitle ? $.i18n(statusTitle) : ""; + let statusHtml = ''; + if(statusValue) { + statusHtml = ' ' + + ' ' + statusValue + ''; + } + + let innerButtonHtml = ''; + let performanceNameField = getDataFieldByLang("performanceName"); + let performanceName = perf[performanceNameField]; + let performanceNameHtml = ' ' + performanceName + ''; + + if(perf.performanceDate){ + let performanceDateTz = DateTime.fromMillis(perf.performanceDate).setZone("UTC+8"); + let performanceDateDisplayFormat = perf.performanceDateDisplayFormat; + let monthYear = getI18nMonthYear(performanceDateTz); + let date = performanceDateTz.day; + let time = (performanceDateDisplayFormat == "DISPLAY_FORMAT_NAME_DATE_TIME") ? getI18nTime(performanceDateTz) : getI18nWeek(performanceDateTz); + let srDate = getI18nSrDate(performanceDateTz); + let monthYearHtml = + '
' + + ' ' + monthYear + ' ' + date + '' + + '
'; + innerButtonHtml += monthYearHtml + + '
' + + ' ' + time +'' + performanceNameHtml + statusHtml + + '
'; + } + else { + innerButtonHtml += ' ' + performanceName + ''+ statusHtml; + } + + let perfId = perf.performanceId; + let isPurchasable = perf.isPurchasable; + let disabledHtml = !isPurchasable || perf.status == 'SOLDOUT' ? 'disabled="disabled"' : ''; + let perfHtml = ''; + + return perfHtml; +} + +let myCalendar = null; +let selDate = null; +var fillCalendar = function(perfData){ + let formattedDatePrefData = perfData.performances.map((item)=>{ + return{ + ...item, + performanceDate: moment(item.performanceDate).format("DD/MM/YYYY") + } + }) + + let formattedDateArr = perfData.performances.map((item)=>{ + if(item.performanceDate){ + return moment(item.performanceDate).format("DD/MM/YYYY") + } + }) + + let min = formattedDatePrefData.find(item =>item.status !== "SOLDOUT").performanceDate; + let max = formattedDatePrefData[formattedDatePrefData.length-1].performanceDate; + + let calendarBox = isMobileFun() ? $('.calendar-box')[0] : $('.calendar-box')[$('.calendar-box').length -1] + let dateBox = isMobileFun() ? $('.date-box')[0] : $('.date-box')[$('.date-box').length -1]; + + $(calendarBox).empty(); + myCalendar = jsCalendar.new(calendarBox, min, { + "monthFormat": "YYYY/##", + "dayFormat": "DDD", + }); + + myCalendar.min(min); + myCalendar.max(max); + + $('.jsCalendar table td').mouseover(function(){ + if(!$(this).hasClass('jsCalendar-previous') && !$(this).hasClass('jsCalendar-next') && !$(this).hasClass('jsCalendar-noPerfDate')){ + let day = $(this)[0].innerText < 10 ? '0'+$(this)[0].innerText : $(this)[0].innerText; + let date = $('.jsCalendar-title-name')[0].innerText + '/' + day; + let formatDate = date.split('/').reverse().join('/') + + let sameDatePref = fillterCurrentDatePrefList(perfData,formattedDatePrefData,formatDate); + let sameDatePrefTimes = [] + sameDatePref.performances.forEach(function(perf) { + if(perf.performanceDate){ + let performanceDateTz = DateTime.fromMillis(perf.performanceDate).setZone("UTC+8"); + let time = (perf.performanceDateDisplayFormat == "DISPLAY_FORMAT_NAME_DATE_TIME") ? getI18nTime(performanceDateTz) : getI18nWeek(performanceDateTz); + let getTime = time.split(', ')[1] ? time.split(', ')[1] : time.split(', ')[1]; + let getEventName = $('#eventName').text() ? $('#eventName').text() : $('.item-title:visible').text(); + sameDatePrefTimes.push( getTime + ' ' + getEventName + '
'); + } + }) + let title = sameDatePrefTimes.join('') + $(this).attr('title', title); + $(this).attr('data-toggle', 'tooltip'); + $(this).attr('data-placement', 'top'); + $(this).attr('data-html', true); + $(this).tooltip('show'); + } + }); + + myCalendar.onDateClick(function(event,date){ + const formatDate = jsCalendar.tools.dateToString(date, "DD/MM/yyyy"); + + let curClickMonth = formatDate.split('/')[1]; + let curDisplayMonth = $('.jsCalendar-title-name')[0].innerText.split('/')[1]; + let isCurMonth = curClickMonth == curDisplayMonth ? true : false; + + selDate = formatDate; + if(formattedDateArr.indexOf(formatDate)!== -1 && isCurMonth){ + myCalendar.clearselect(); + + if($('.jsCalendar-selected').length){ + toSelDate = null; + $('.jsCalendar-selected')[0].classList.remove('jsCalendar-selected') + } + myCalendar.select(formatDate); + fillterCurrentDatePrefList(perfData,formattedDatePrefData,formatDate) + dateBox.classList.remove("d-none") + + } + }) + + let toSelDate = null; + if (selectedPerfId) { + toSelDate = formattedDatePrefData.find(i => i.performanceId == selectedPerfId).performanceDate; + myCalendar.goto(toSelDate) + myCalendar.select(toSelDate) + }else{ + myCalendar.goto(selDate); + selDate ? myCalendar.select(selDate) : myCalendar.select(min); + } + + myCalendar.onDateRender(function(date, element, info) { + const formatDate = jsCalendar.tools.dateToString(date, "DD/MM/yyyy"); + + element.classList.remove('jsCalendar-soldout') + + if(formattedDateArr.indexOf(formatDate) === -1){ + element.classList.add('jsCalendar-noPerfDate') + } + + let obj = {}; + let newArr = []; + formattedDatePrefData.forEach(item => { + if (!obj[item.performanceDate]) { + var arr = []; + arr.push(item); + newArr.push(arr); + obj[item.performanceDate] = item; + } else { + newArr.forEach(function (value, index) { + if (value[0].performanceDate == item.performanceDate) { + value.push(item) + } + }) + } + }) + + let soldoutDateArr = [] + newArr.forEach(item =>{ + if(item.every(i => i.status == "SOLDOUT")){ + item.forEach(i => { + if(soldoutDateArr.indexOf(i.performanceDate) == -1){ + soldoutDateArr.push(i.performanceDate) + } + }) + } + }) + + if(soldoutDateArr.indexOf(formatDate) !== -1){ + element.classList.add('jsCalendar-soldout') + } + + if(document.querySelector('.jsCalendar-selected')!== null && document.querySelector('.jsCalendar-current')!== null){ + document.querySelector('.jsCalendar-current').classList.remove('jsCalendar-current') + } + + if(element.classList.contains('jsCalendar-selected')){ + let sameDatePref = fillterCurrentDatePrefList(perfData,formattedDatePrefData,formatDate) + fillPerformanceData(sameDatePref) + postConstruct() + } + + }); + myCalendar.refresh(); + + changePerfCalendarTheme(); + changePerfCalendarLang(); +} + +var fillterCurrentDatePrefList = function(perfData,formattedDatePrefData,curDate){ + let sameDatePerfIdArr = [] + formattedDatePrefData.forEach(i =>{ + if(i.performanceDate === curDate){ + return sameDatePerfIdArr.push(i.performanceId) + } + }) + + let sameDatePref = {} + sameDatePref.performances = [] + perfData.performances.forEach(pref =>{ + sameDatePerfIdArr.forEach(id =>{ + if(pref.performanceId === id){ + sameDatePref.performances.push(pref) + } + }) + }) + return sameDatePref; +} + +var changePerfCalendarTheme = function(){ + if(Cookies.get('cl-theme-color') == 'black'){ + document.querySelector('.jsCalendar').classList.remove('grey-theme') + document.querySelector('.jsCalendar').classList.add('black-theme') + }else if(Cookies.get('cl-theme-color') == 'night'){ + document.querySelector('.jsCalendar').classList.remove('black-theme') + document.querySelector('.jsCalendar').classList.add('grey-theme') + }else{ + document.querySelector('.jsCalendar').classList.remove('black-theme') + document.querySelector('.jsCalendar').classList.remove('grey-theme') + } +} + +var changePerfCalendarLang = function(){ + if(get_lang() !== 'en'){ + myCalendar.setLanguage("zh") + }else{ + myCalendar.setLanguage("en") + } +} + +var handleEventNotAvail = function() { + let html = '
' + $.i18n("event-not-available-msg") + "
"; + $(".main").html(html); + $("footer").addClass("fixed-bottom"); +} + + +var utsvEventListCache = null; +var eventLikeListCache = null; +var isExpired = function(expiry) { + return (new Date(expiry) < new Date()); +} +var getClUtsvEventByUtsvId = function(utsvId) { + var result = (!utsvEventListCache) ? null : + utsvEventListCache.filter(function(val, i) { + return (val.utsvId == utsvId); + }); + return (result) ? result[0]: null; +} +var getLikeCountById = function(evtId) { + var clEvt = getClUtsvEventByUtsvId(evtId); + var jsonCount = (clEvt) ? clEvt.likeCount : 0; + var cookieCount = (clEvt) ? Cookies.get('cl-like-' + clEvt.id) || 0 : 0; + return Math.max(jsonCount, cookieCount); +} +var isLikedEvent = function(evtId) { + var clEvt = getClUtsvEventByUtsvId(evtId); + // var cookieLike = (clEvt) ? Cookies.get('cl-like-' + clEvt.id) || 0 : 0; + // var result = (eventLikeListCache && clEvt) ? eventLikeListCache.indexOf(clEvt.id) : null; + // return (cookieLike || result >= 0); + let result + if(isCitylineLogin){ + result = (eventLikeListCache && clEvt) ? eventLikeListCache.indexOf(clEvt.id) : null; + return result !== null && result >= 0 + }else{ + var list = JSON.parse(localStorage.getItem("not-login-like-utsvEvent")); + result = (list && clEvt) ? list.indexOf(clEvt.id) : null; + return result !== null && result >= 0 + } +} +var drawLikeButton = function(evtId) { + var likeCount = getLikeCountById(evtId); + if(likeCount || likeCount == 0) + $('.likeCount').text(likeCount); + + if(isLikedEvent(evtId)) + $('.likeIcon').addClass('liked'); + else + $('.likeIcon').removeClass('liked'); + + if(getClUtsvEventByUtsvId(evtId)) $('#likeButton').show(); +} +var getLatestClUtsvEventList = function() { + // var url = citylineDomainUrl+'/api/utsvEventList.do'; + var url = citylineDomainUrl+'/data/utsvEventList.json'; + return $.get({url: url, global: false}, function(data, status) { + if(data && data.utsvEventList) { + utsvEventListCache = data.utsvEventList; + utsvEventListCache = utsvEventListCache.map(function(etv) { + var newEvt = {}; + newEvt['id'] = etv.id; + newEvt['utsvId'] = etv.utsvId; + newEvt['likeCount'] = etv.likeCount; + newEvt['synonym'] = etv.synonym; + return newEvt; + }); + var expiry = 15; // in minutes + var localList = { + utsvEventListCache, + 'expiry': new Date(new Date().getTime() + (expiry*60*1000)).getTime() + } + localStorage.setItem("like-count-utsvEvent", JSON.stringify(localList)); + + var eventId = getUrlParameter('event'); + drawLikeButton(eventId); + } + }).fail(function(){ + // console.log("failed to call /api/utsvEventList.do"); + console.log("failed to call /data/utsvEventList.json"); + }); +} +var getClUtsvEventList = function() { + var deferred = $.Deferred(); + var list = JSON.parse(localStorage.getItem('like-count-utsvEvent')); + if (!list || (list.expiry && isExpired(list.expiry))) { + return getLatestClUtsvEventList(); + } else { + utsvEventListCache = list.utsvEventListCache; + var eventId = getUrlParameter('event'); + drawLikeButton(eventId); + + return deferred; + } +} +var getLatestEventLikeList = function() { + var url = citylineDomainUrl + '/api/customer/favourite.do'; + return $.get({ + url: url, + global: false, + xhrFields: { + withCredentials: true + } + }, function(data, status) { + if(data && data.utsvEventIds) { + eventLikeListCache = data.utsvEventIds; + var expiry = 15; // in minutes + var localList = { + 'likeList': eventLikeListCache, + 'expiry': new Date(new Date().getTime() + (expiry*60*1000)).getTime() + } + if(isCitylineLogin){ + localStorage.setItem("like-list-utsvEvent", JSON.stringify(localList)); + } + var eventId = getUrlParameter('event'); + drawLikeButton(eventId); + } + }).fail(function(){ + console.log("failed to call /api/customer/favourite.do"); + }); +} +var getEventLikeList = function() { + var deferred = $.Deferred(); + var likeListJson = JSON.parse(localStorage.getItem('like-list-utsvEvent')); + if (!likeListJson || (likeListJson.expiry && isExpired(likeListJson.expiry))) { + return getLatestEventLikeList(); + } else { + eventLikeListCache = likeListJson.likeList; + var eventId = getUrlParameter('event'); + drawLikeButton(eventId); + + return deferred; + } +} +var setupLikeFeature = function() { + $.when(getClUtsvEventList()) + .then(getEventLikeList()); +} +var doLikeThisEvent = function(evtId) { + var clEvt = getClUtsvEventByUtsvId(evtId); + var isLiked =isLikedEvent(evtId); + if(clEvt && !isLiked) { + var url = citylineDomainUrl + '/api/customer/favourite/utsvEvent/' + clEvt.id + '.do'; + console.log('like!', 'utsvId: ' + evtId, 'revamp id: ' + clEvt.id); + return $.post({ + url: url, + xhrFields: { + withCredentials: true + }, + global: false + }, function(data, status, xhr){ + var clEvtId = clEvt.id + var expiry = 60; // in minutes + var expires = new Date(new Date().getTime() + (expiry*60*1000)); + + if(isCitylineLogin){ + + if(Cookies.get('cl-like-' + clEvt.id)){ + var likeCount = +Cookies.get('cl-like-' + clEvt.id) + 1; + }else{ + var likeCount = clEvt.likeCount + 1; + } + + getLatestEventLikeList() + }else{ + var likeCount = clEvt.likeCount + 1; + var notLoginLikeList = JSON.parse(localStorage.getItem("not-login-like-utsvEvent") || "[]"); + notLoginLikeList.push(clEvtId); + localStorage.setItem("not-login-like-utsvEvent",JSON.stringify(notLoginLikeList)) + } + Cookies.set('cl-like-' + clEvtId, likeCount, { expires }); + drawLikeButton(evtId); + return true; + }).fail(function() { + return false; + }); + } +} \ No newline at end of file diff --git a/webdriver/Maxbot_1.0.0/js/cityline_event_detail.js b/webdriver/Maxbot_1.0.0/js/cityline_event_detail.js new file mode 100644 index 0000000..cad914b --- /dev/null +++ b/webdriver/Maxbot_1.0.0/js/cityline_event_detail.js @@ -0,0 +1,309 @@ +var eventDataCache = null; +var performanceDataCache = null; +var selectedPerfId = null; +var perfPriceListMap = null; +var pageLoaded = false; +var eventImageUrl = null; +var perfDisplayStyle = null; +var allPerformanceDataCache = null; +var contextPath = "/utsvInternet"; + +var showEnlargedImage = function(image){ + if(image === 'event'){ + $('.image').attr('src', eventImageUrl); + } + $("#commonImageModal").modal('show'); +} + +var addToCalendar = function() { + if(eventDataCache && eventDataCache.eventDate){ + let addToCalButton= document.querySelector('add-to-calendar-button') + + localStorage.getItem('theme-color') == 'black'? addToCalButton.setAttribute('lightMode','dark') : addToCalButton.removeAttribute('lightMode') + + let options = []; + options.push('Google|'+ $.i18n("calendar-google")) + options.push('iCal|'+ $.i18n("calendar-ical")) + options.push('Outlook.com|'+ $.i18n("calendar-outlook")) + addToCalButton.setAttribute('options',JSON.stringify(options)) + + let customLabels = { + 'close': $.i18n("calendar-close"), + 'label.addtocalendar': $.i18n("calendar-label-addtocalendar") + }; + addToCalButton.setAttribute('customLabels',JSON.stringify(customLabels)) + + let venueNameField = getDataFieldByLang("venueName") + addToCalButton.setAttribute('location',eventDataCache.venue[venueNameField]) + + $("#addToCal").show(); + + if(performanceDataCache){ + if(performanceDataCache.performances && performanceDataCache.performances.length > 0) { + let dates = [] + performanceDataCache.performances.forEach(perf =>{ + let performanceNameField = getDataFieldByLang("performanceName"); + let performanceName = perf[performanceNameField]; + + if(performanceDataCache.performances.length == 1){ + addToCalButton.setAttribute('name', performanceName) + addToCalButton.setAttribute('startDate', moment(perf.performanceDate).format("YYYY-MM-DD")) + }else{ + let prefDate = { + name: performanceName, + startDate: moment(perf.performanceDate).format("YYYY-MM-DD") + } + dates.push(prefDate) + } + }) + + if(performanceDataCache.performances.length > 1) addToCalButton.setAttribute('dates',JSON.stringify(dates)) + + } + } + } +} + +var fillEventData = function(data) { + console.log("eventData:", data); + eventDataCache = data; + eventImageUrl = data.eventLargeCoverUrl + + let eventStatues = {"TOBESOLD" : "event-status-tobesold", "SALE" : "event-status-sale", "SOLDOUT" : "event-status-soldout", "EXPIRED" : "event-status-expired"}; + if(data.status=="TOBESOLD") location.reload(); + if(data.status=="SOLDOUT") location.reload(); +} + +var openWindow = function(url) { + let citylineWindow = window.open(url,"_blank ","width=1020,height=600,top=0,left=20,resizable=yes,menubar=no,scrollbars=yes,status=yes"); + citylineWindow.focus(); +} + +var fillPerformanceData = function(data) { + console.log("eventPerfData:", data); + performanceDataCache = data; + perfPriceListMap = new Map(); + //selectedPerfId = null; + let perfHtml = ""; + if(data.performances && data.performances.length > 0) { + + let fillerPerId = []; + data.performances.forEach(i => fillerPerId.push(i.performanceId)) + + data.performances.forEach(function(perf, i) { + perfHtml += getPerfHtml(perf) + perfPriceListMap.set(perf.performanceId, perf.pricelist); + + if(perfDisplayStyle === 'DEFAULT'){ + if(!selectedPerfId && perf.status != 'SOLDOUT') selectedPerfId = perf.performanceId; + }else if(perfDisplayStyle === 'CALENDAR'){ + if(!selectedPerfId && perf.status != 'SOLDOUT') selectedPerfId = perf.performanceId; + + if(!fillerPerId.includes(+selectedPerfId)){ + if(perf.status != 'SOLDOUT') selectedPerfId = perf.performanceId; + } + + } + + /* Google Analytics */ + var formatDate = new Date(perf.performanceDate); + var item = { + id : "[" + eventSynonym + "] " + formatForGoogleAnalytics(formatDate), // 2021/08/14 23:59 (Sat) + name : event_en, + category : "[" + eventSynonym + "] " + formatForGoogleAnalytics(formatDate), + list_position : i + }; + viewItems.push(item); + + if (i == 0) { + googleAnalyticViewItem(perf.performanceId, formatForGoogleAnalytics(perf.performanceDate)); + } + }); + + googleAnalyticViewItemList(); + + $(".date-box").html(perfHtml); + selectPerf(); + + } + else { + $(".date-title").addClass("d-none"); + } +} + +var getPerfById = function(perfId) { + var perfList = performanceDataCache.performances; + if(perfList && perfList.length > 0) { + return perfList.find(perf => perf.performanceId == perfId) + } else { + return null; + } +} + +var fillPriceList = function(perfId) { + let priceList = perfPriceListMap.get(perfId); + let ticketPriceHtml = getTicketPriceHtml(priceList); + $(".puchase-bottom").html(ticketPriceHtml); +} + +var selectPerf = function() { + if(selectedPerfId){ + $('button.date-time-position').attr("aria-pressed", false); + let selectedElement = $("*[data-perf-id='" + selectedPerfId + "']"); + selectedElement.addClass("item-onclick"); + selectedElement.attr("aria-pressed", true); + fillPriceList(selectedPerfId); + + var perf = getPerfById(selectedPerfId); + if (perf) { + var perfDate = new Date(perf.performanceDate); + googleAnalyticViewItem(selectedPerfId, formatForGoogleAnalytics(perfDate)); + } + } +} + +var getTicketPriceHtml = function(priceList){ + let ticketPriceHtml = ""; + if(priceList){ + priceList.sort((a, b) => (a.price > b.price) ? -1 : 1); + priceList.forEach(function(pl) { + let statusHtml = ""; + if(pl.status == 'LIMIT' || pl.status == 'SOLDOUT'){ + statusHtml = ''; + } + ticketPriceHtml += ' '; + }); + } + + ticketPriceHtml = '
' + + '
' + $.i18n("price-title" ) + '
' + + '
'+ ticketPriceHtml + '
' + + '
' + + '
' + + ' ' + + '
'; + + return ticketPriceHtml; + +} + +var postConstruct = function(){ + $(".date-time-position").click(function(){ + $('button.date-time-position').attr("aria-pressed", false); + $(".item-onclick").removeClass("item-onclick"); + $(this).addClass("item-onclick"); + $(this).attr("aria-pressed", true); + let perfId = $(this).data("perf-id"); + selectedPerfId = perfId; + fillPriceList(perfId); + setPurchaseBtnClick(); + }); + + $('#likeButton').on('click', function() { + var eventId = getUrlParameter('event'); + if(doLikeThisEvent(eventId)) + $('.likeIcon').addClass('liked'); + }) + + setPurchaseBtnClick(); + if (needToPurchase) { + $(".purchase-btn").click(); + } + + // hide presenter if repeated + if($("[data-i18n=event-presenter]").text() == $("#firstDesc div p:first-child").text()) { + $("[data-i18n=event-presenter]").parent().hide(); + } +} + + +var purchaseBtnClick = function() { + $.LoadingOverlay("show"); + var eventId = getUrlParameter('event'); + var url = contextPath + "/internet/performance?event=[eventId]&perfId=[perfId]"; + url = url.replace("[eventId]", eventId) + .replace("[perfId]",selectedPerfId) + location.href = url; + $.LoadingOverlay("close"); +} + +var setPurchaseBtnClick = function() { + $(".purchase-btn").click(function () { + if(hasLoggedIn){ + purchaseBtnClick(); + } + else { + var addParams = []; + if(selectedPerfId) + addParams.push('perfId=' + selectedPerfId); + //console.log('addParams', addParams) + loginCallback = purchaseBtnClick; + login(true, addParams); + } + }); +} + +var reloadFromCache = function() { + fillEventData(eventDataCache); + if(perfDisplayStyle === 'DEFAULT'){ + fillPerformanceData(performanceDataCache); + }else if(perfDisplayStyle === 'CALENDAR'){ + fillCalendar(allPerformanceDataCache) + } + postConstruct(); +} + +var loadArchiveUrl = function(archiveUrl) { + $.ajax({ + type : "GET", + dataType: "json", + url: archiveUrl, + async: false, + global: false, + cache: true, + success: function(data) { + fillEventData(data); + }, + statusCode: { + 403: function() { + handleEventNotAvail(); + } + }, + }); +} + +var loadData = function() { + let eventId = getUrlParameter('event'); + if(eventId){ + let eventRequestUrl = contextPath + "/internet/api/event/" + eventId; + let eventPerfRequestUrl = contextPath + "/internet/api/event/" + eventId + "/performances"; + return $.when($.getJSON(eventRequestUrl)).then(function(data){ + if(data.eventId) fillEventData(data); + else if (data.archiveUrl){ + //$(".date-title").addClass("d-none"); + loadArchiveUrl(data.archiveUrl); + } + else handleEventNotAvail(); + + perfDisplayStyle = data.performancesDisplayStyle; + return $.getJSON(eventPerfRequestUrl); + }).then(function(data){ + allPerformanceDataCache = data; + }); + } + else { + console.log("no event specified"); + } +} + + +console.log("start my extension"); + +selectedPerfId = getUrlParameter('perfId'); +if(pageLoaded) { + reloadFromCache(); +}else{ + pageLoaded = true; + loadData(); +} + diff --git a/webdriver/Maxbot_1.0.0/js/tixcraft_area.js b/webdriver/Maxbot_1.0.0/js/tixcraft_area.js index 3fd04d4..423e788 100644 --- a/webdriver/Maxbot_1.0.0/js/tixcraft_area.js +++ b/webdriver/Maxbot_1.0.0/js/tixcraft_area.js @@ -1,3 +1,97 @@ +const storage = chrome.storage.local; +var settings = null; + $("ul.area-list > li:not(:has(a))").remove(); $("#selectseat div div img").remove(); -$("footer").remove(); \ No newline at end of file +$("footer").remove(); +if ($("ul.area-list > li:has(a)").length) { + storage.get('settings', function (items) + { + if (items.settings) + { + settings = items.settings; + + //console.log("area_mode:"+ settings.area_auto_select.mode); + //console.log("area_keyword:"+ settings.area_auto_select.area_keyword); + //console.log("keyword_exclude:"+ settings.keyword_exclude); + let exclude_keyword_array = []; + if(settings.keyword_exclude.length > 0) { + exclude_keyword_array = JSON.parse('[' + settings.keyword_exclude +']'); + } + for (let i = 0; i < exclude_keyword_array.length; i++) { + $("ul.area-list > li > a:contains('"+ exclude_keyword_array[i] +"')").each(function () + { + $(this).parent().remove(); + } + ); + } + + { + let area_keyword_array = []; + if(settings.area_auto_select.area_keyword.length > 0) { + area_keyword_array = JSON.parse('[' + settings.area_auto_select.area_keyword +']'); + } + console.log(area_keyword_array); + let target_area; + if(area_keyword_array.length) { + for (let i = 0; i < area_keyword_array.length; i++) { + let query_string = "ul.area-list > li > a:contains('"+ area_keyword_array[i] +"')"; + if(area_keyword_array[i]=="") { + query_string = "ul.area-list > li > a" + } + if(settings.tixcraft.area_auto_select.mode=="from top to bottom") + target_area = $(query_string).first(); + if(settings.tixcraft.area_auto_select.mode=="from bottom to top") + target_area = $(query_string).last(); + if(settings.tixcraft.area_auto_select.mode=="center") + target_area = $(query_string).first(); + if(settings.tixcraft.area_auto_select.mode=="random") + target_area = $(query_string).first(); + + if (target_area.length) { + console.log("match keyword:" + area_keyword_array[i]); + break; + } + } + } else { + target_area = $("ul.area-list > li > a").first(); + } + + if (target_area.length) { + let link_id = target_area.attr("id"); + //console.log("link_id: " + link_id); + if(link_id) { + let body = document.body.innerHTML; + let areaUrlList = null; + if(body.indexOf('var areaUrlList =')>-1) { + const javasrit_right = body.split('var areaUrlList =')[1]; + let areaUrlHtml = ""; + if(javasrit_right) { + areaUrlHtml = javasrit_right.split("};")[0]; + } + if(areaUrlHtml.length > 0) { + areaUrlHtml = areaUrlHtml + "}"; + areaUrlList = JSON.parse(areaUrlHtml); + } + //console.log(areaUrlHtml); + } + + let new_url = null; + if(areaUrlList) { + let new_url = areaUrlList[link_id]; + if (new_url) { + //console.log(new_url); + window.location.href = new_url + } + } + } + } else { + console.log("not target_area found.") + } + } + + } + }); +} else { + location.reload(); +} \ No newline at end of file diff --git a/webdriver/Maxbot_1.0.0/js/tixcraft_detail.js b/webdriver/Maxbot_1.0.0/js/tixcraft_detail.js new file mode 100644 index 0000000..36c79fc --- /dev/null +++ b/webdriver/Maxbot_1.0.0/js/tixcraft_detail.js @@ -0,0 +1,10 @@ +(function () { + const currentUrl = window.location.href; + const event_code = currentUrl.split('/')[5]; + //console.log(currentUrl); + //console.log(event_code); + if(event_code){ + let new_url = "https://tixcraft.com/activity/game/"+ event_code; + location.href=new_url; + } +})(); diff --git a/webdriver/Maxbot_1.0.0/js/tixcraft_game.js b/webdriver/Maxbot_1.0.0/js/tixcraft_game.js index 9811314..afe343c 100644 --- a/webdriver/Maxbot_1.0.0/js/tixcraft_game.js +++ b/webdriver/Maxbot_1.0.0/js/tixcraft_game.js @@ -1 +1,84 @@ -$("footer").remove(); \ No newline at end of file +const storage = chrome.storage.local; +var settings = null; +var myInterval = null; + +$("div.masthead-wrap").remove(); +if ($("#gameList button").length) { + remove_list=['Currently Unavailable', + 'Sale ended on 20', + 'Sold out', + '暫停販售', + ':00 截止', + '已售完', + '00に発売終了', + '販売一時中止', + '完売した' + ]; + for (let i = 0; i < remove_list.length; i++) { + $("#gameList td:contains('"+ remove_list[i] +"')").each(function () + { + $(this).parent().remove(); + } + ); + } + if ($("#gameList button").length) { + storage.get('settings', function (items) + { + if (items.settings) + { + settings = items.settings; + myInterval = setInterval(() => { + //console.log("date_mode:"+ settings.tixcraft.date_auto_select.mode); + //console.log("date_keyword:"+ settings.tixcraft.date_auto_select.date_keyword); + let date_keyword_array = []; + if(settings.tixcraft.date_auto_select.date_keyword.length > 0) { + date_keyword_array = JSON.parse('[' + settings.tixcraft.date_auto_select.date_keyword +']'); + } + //console.log(date_keyword_array); + let target_date; + if(date_keyword_array.length) { + for (let i = 0; i < date_keyword_array.length; i++) { + let query_string = "#gameList td:contains('"+ date_keyword_array[i] +"')"; + if(date_keyword_array[i]=="") { + query_string = "#gameList td" + } + if(settings.tixcraft.date_auto_select.mode=="from top to bottom") + target_date = $(query_string).first(); + if(settings.tixcraft.date_auto_select.mode=="from bottom to top") + target_date = $(query_string).last(); + if(settings.tixcraft.date_auto_select.mode=="center") + target_date = $(query_string).first(); + if(settings.tixcraft.date_auto_select.mode=="random") + target_date = $(query_string).first(); + + if (target_date.length) { + //console.log("match keyword:" + date_keyword_array[i]); + break; + } + } + } else { + target_date = $("#gameList td").first(); + } + + if (target_date.length) { + let link = target_date.parent().find("button").attr("data-href"); + if (link) { + //console.log("link: " + link); + clearInterval(myInterval); + window.location.href = link; + } + } else { + //console.log("not target_date found.") + } + }, 200); + } else { + console.log('no settings found'); + } + }); + + } else { + location.reload(); + } +} else { + location.reload(); +} \ No newline at end of file diff --git a/webdriver/Maxbot_1.0.0/js/tixcraft_home.js b/webdriver/Maxbot_1.0.0/js/tixcraft_home.js index 0ebe0c3..b33421f 100644 --- a/webdriver/Maxbot_1.0.0/js/tixcraft_home.js +++ b/webdriver/Maxbot_1.0.0/js/tixcraft_home.js @@ -1,2 +1,4 @@ $("#newsHome").remove(); $("footer").remove(); +$("#topAlert").remove(); +$("div.darkBg > div.container > div.row").remove(); \ No newline at end of file diff --git a/webdriver/Maxbot_1.0.0/js/tixcraft_ticket.js b/webdriver/Maxbot_1.0.0/js/tixcraft_ticket.js index 78f1249..e924161 100644 --- a/webdriver/Maxbot_1.0.0/js/tixcraft_ticket.js +++ b/webdriver/Maxbot_1.0.0/js/tixcraft_ticket.js @@ -1,3 +1,6 @@ +const storage = chrome.storage.local; +var settings = null; + $('input[type=checkbox]').each(function () { $(this).prop('checked', true); @@ -35,14 +38,16 @@ function assign_ticket_number(ticket_number) } } -function initSettings() -{ - fetch(chrome.extension.getURL("/data/settings.json")) - .then((resp) => resp.json()) - .then((settings) => +(function () { + storage.get('settings', function (items) { - assign_ticket_number(settings.ticket_number); - } - ); -} -initSettings(); + if (items.settings) + { + settings = items.settings; + console.log("ticket_number:"+ settings.ticket_number); + assign_ticket_number(settings.ticket_number); + } else { + console.log('no settings found'); + } + }); +})(); diff --git a/webdriver/Maxbot_1.0.0/manifest.json b/webdriver/Maxbot_1.0.0/manifest.json index b4fe238..4ffe94e 100644 --- a/webdriver/Maxbot_1.0.0/manifest.json +++ b/webdriver/Maxbot_1.0.0/manifest.json @@ -13,14 +13,24 @@ "background": { "service_worker": "background.js" }, - "minimum_chrome_version": "77.0", + "declarative_net_request": { + "rule_resources": [ + { + "id": "ruleset_1", + "enabled": true, + "path": "rules_1.json" + } + ] + }, "permissions": [ "activeTab", "storage", "scripting", "tabs", "webNavigation", - "webRequest" + "webRequest", + "declarativeNetRequest", + "declarativeNetRequestFeedback" ], "web_accessible_resources": [ { @@ -45,6 +55,11 @@ "run_at": "document_end", "js" : [ "jquery.min.js", "js/tixcraft_game.js" ] }, + { + "matches" : [ "https://tixcraft.com/activity/detail/*" ], + "run_at": "document_end", + "js" : [ "jquery.min.js", "js/tixcraft_detail.js" ] + }, { "matches" : [ "https://tixcraft.com/ticket/ticket/*" ], "run_at": "document_end", @@ -70,6 +85,11 @@ "run_at": "document_end", "js" : [ "jquery.min.js", "js/ibon_area.js" ] }, + { + "matches" : [ "https://*.cityline.com/utsvInternet/internet/eventDetail?event=*" ], + "run_at": "document_end", + "js" : [ "jquery.min.js", "js/cityline_event_common.js","js/cityline_event_detail.js" ] + }, { "matches" : [ "https://kktix.com/events/*/registrations/new" diff --git a/webdriver/Maxbot_1.0.0/rules_1.json b/webdriver/Maxbot_1.0.0/rules_1.json new file mode 100644 index 0000000..1d3725c --- /dev/null +++ b/webdriver/Maxbot_1.0.0/rules_1.json @@ -0,0 +1,245 @@ +[ + { + "id": 1, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*google-analytics.com/*", + "resourceTypes": ["main_frame", "sub_frame"] + } + }, + { + "id": 2, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*googletagmanager.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 3, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*googletagservices.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 4, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*lndata.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 5, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*a.amnet.tw/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 6, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*ad.setn.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 7, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*adx.c.appier.net/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 8, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*cbcapi.setn.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 9, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*clarity.ms/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 10, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*cloudfront.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 11, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*cms.analytics.yahoo.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 12, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*doubleclick.net/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 13, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*e2elog.fetnet.net/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 14, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*fundingchoicesmessages.google.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 15, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*ghtinc.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 16, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*match.adsrvr.org/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 17, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*onead.onevision.com.tw/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 18, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*popin.cc/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 19, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*rollbar.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 20, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*sb.scorecardresearch.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 21, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*t.ssp.hinet.net/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 22, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*tagtoo.co/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 23, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*t.ssp.hinet.net/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 24, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*ticketmaster.sg/js/adblock*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 25, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*tpc.googlesyndication.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 26, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*treasuredata.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + }, + { + "id": 27, + "priority": 1, + "action": { "type": "block"}, + "condition": { + "urlFilter": "*ubas.setn.com/*", + "resourceTypes": ["main_frame", "sub_frame", "script", "image", "font", "xmlhttprequest", "media"] + } + } +]