Latest commit

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CalMerge

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar. Runs on a LAMP stack.

Installation

NOTE: If you don't know what a LAMP stack is, it's best to read up on that first. If you're just starting out, feel free to get in touch with me and I can try to answer any questions you have! Also note that your LAMP stack must support cURL to access external URLs and that some providers block this functionality in their basic plans.

  1. Create a new MySQL database and import the database structure found in Database/Database.sql
  2. Upload the files in the PHP folder to a directory on your server — most likely a folder that a subdomain points to.
  3. Modify PHP/config.php:
    • Add your username, password, and database name
    • Change the sharePrefix. This is the URL that users will import your calendar with and needs to correspond to the URL rewriting that goes on in .htaccess.
    • Change the name of the merged output if you desire.
  4. Modify PHP/index.php:
    • This is just a page that redirects people if they just type in the initial part of the share URL. It could redirect to your homepage or something like Google.
  5. Modify the .htaccess file. Many operating systems see this as a hidden file, so be sure that it gets uploaded. This rewrites URLs into a nicer format and restricts access to settings. You will need to create an .htpasswd file that this links to. Some providers have a built in utility to do this. In that case, it might be easiest to delete the AuthName and AuthUserFile lines and use their utility.
  6. Be sure to create an .htpasswd file that protects the files in the admin folder.

Use

  1. Navigate to admin/index.php
  2. If using a service like iCloud, create public share links of all the calendars you intend to merge.
  3. Add calendars with the "+" button in the top right of the "Calendars" panel. Each calendar should have a name, a URL, and a color (in HEX, without the pound sign).
  4. Add viewers with the "+" button in the top right of the "Viewers" panel. Each viewer gets a name and a list of Calendars that they should have read access to. Modify their access through the checkboxes that appear under their name.
  5. Note that events may take up to 48 hours to process in Google Calendar. This is because they aggressively cache subscribed calendars.

FAQs

  • Q: But isn't this a public copy of my calendar? Can't anyone access it?
    • A: Yes. In theory, anyone can access the public link that you create, though it's extremely unlikely. This utility also allows you to revoke access to certain people without destroying your whole calendar.
  • Q: Why won't Google Calendar update?
    • A: Google Calendar aggressively caches subscribed calendars and there's a 24-48 hour lag window. It's supposed to be closer to 8 hours, but I've had worse luck. I realize this isn't ideal, but there's nothing I can personally do about this. Read Google's answer here.

Known Issues / To-Dos

  • It would be great to have a color picker when adding a new calendar. Or a service that attempts to recognize the color that's already been set for the calendar.
  • Timezone support is seriously lacking. For right now, known timezones exist in a static file called timezones.txt that is placed at the top of every merge output. A better implementation would aggregate timezones from calendars being merged.

About

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CalMerge

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar. Runs on a LAMP stack.

Installation

NOTE: If you don't know what a LAMP stack is, it's best to read up on that first. If you're just starting out, feel free to get in touch with me and I can try to answer any questions you have! Also note that your LAMP stack must support cURL to access external URLs and that some providers block this functionality in their basic plans.

  1. Create a new MySQL database and import the database structure found in Database/Database.sql
  2. Upload the files in the PHP folder to a directory on your server — most likely a folder that a subdomain points to.
  3. Modify PHP/config.php:
    • Add your username, password, and database name
    • Change the sharePrefix. This is the URL that users will import your calendar with and needs to correspond to the URL rewriting that goes on in .htaccess.
    • Change the name of the merged output if you desire.
  4. Modify PHP/index.php:
    • This is just a page that redirects people if they just type in the initial part of the share URL. It could redirect to your homepage or something like Google.
  5. Modify the .htaccess file. Many operating systems see this as a hidden file, so be sure that it gets uploaded. This rewrites URLs into a nicer format and restricts access to settings. You will need to create an .htpasswd file that this links to. Some providers have a built in utility to do this. In that case, it might be easiest to delete the AuthName and AuthUserFile lines and use their utility.
  6. Be sure to create an .htpasswd file that protects the files in the admin folder.

Use

  1. Navigate to admin/index.php
  2. If using a service like iCloud, create public share links of all the calendars you intend to merge.
  3. Add calendars with the "+" button in the top right of the "Calendars" panel. Each calendar should have a name, a URL, and a color (in HEX, without the pound sign).
  4. Add viewers with the "+" button in the top right of the "Viewers" panel. Each viewer gets a name and a list of Calendars that they should have read access to. Modify their access through the checkboxes that appear under their name.
  5. Note that events may take up to 48 hours to process in Google Calendar. This is because they aggressively cache subscribed calendars.

FAQs

  • Q: But isn't this a public copy of my calendar? Can't anyone access it?
    • A: Yes. In theory, anyone can access the public link that you create, though it's extremely unlikely. This utility also allows you to revoke access to certain people without destroying your whole calendar.
  • Q: Why won't Google Calendar update?
    • A: Google Calendar aggressively caches subscribed calendars and there's a 24-48 hour lag window. It's supposed to be closer to 8 hours, but I've had worse luck. I realize this isn't ideal, but there's nothing I can personally do about this. Read Google's answer here.

Known Issues / To-Dos

  • It would be great to have a color picker when adding a new calendar. Or a service that attempts to recognize the color that's already been set for the calendar.
  • Timezone support is seriously lacking. For right now, known timezones exist in a static file called timezones.txt that is placed at the top of every merge output. A better implementation would aggregate timezones from calendars being merged.

About

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CalMerge

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar. Runs on a LAMP stack.

Installation

NOTE: If you don't know what a LAMP stack is, it's best to read up on that first. If you're just starting out, feel free to get in touch with me and I can try to answer any questions you have! Also note that your LAMP stack must support cURL to access external URLs and that some providers block this functionality in their basic plans.

  1. Create a new MySQL database and import the database structure found in Database/Database.sql
  2. Upload the files in the PHP folder to a directory on your server — most likely a folder that a subdomain points to.
  3. Modify PHP/config.php:
    • Add your username, password, and database name
    • Change the sharePrefix. This is the URL that users will import your calendar with and needs to correspond to the URL rewriting that goes on in .htaccess.
    • Change the name of the merged output if you desire.
  4. Modify PHP/index.php:
    • This is just a page that redirects people if they just type in the initial part of the share URL. It could redirect to your homepage or something like Google.
  5. Modify the .htaccess file. Many operating systems see this as a hidden file, so be sure that it gets uploaded. This rewrites URLs into a nicer format and restricts access to settings. You will need to create an .htpasswd file that this links to. Some providers have a built in utility to do this. In that case, it might be easiest to delete the AuthName and AuthUserFile lines and use their utility.
  6. Be sure to create an .htpasswd file that protects the files in the admin folder.

Use

  1. Navigate to admin/index.php
  2. If using a service like iCloud, create public share links of all the calendars you intend to merge.
  3. Add calendars with the "+" button in the top right of the "Calendars" panel. Each calendar should have a name, a URL, and a color (in HEX, without the pound sign).
  4. Add viewers with the "+" button in the top right of the "Viewers" panel. Each viewer gets a name and a list of Calendars that they should have read access to. Modify their access through the checkboxes that appear under their name.
  5. Note that events may take up to 48 hours to process in Google Calendar. This is because they aggressively cache subscribed calendars.

FAQs

  • Q: But isn't this a public copy of my calendar? Can't anyone access it?
    • A: Yes. In theory, anyone can access the public link that you create, though it's extremely unlikely. This utility also allows you to revoke access to certain people without destroying your whole calendar.
  • Q: Why won't Google Calendar update?
    • A: Google Calendar aggressively caches subscribed calendars and there's a 24-48 hour lag window. It's supposed to be closer to 8 hours, but I've had worse luck. I realize this isn't ideal, but there's nothing I can personally do about this. Read Google's answer here.

Known Issues / To-Dos

  • It would be great to have a color picker when adding a new calendar. Or a service that attempts to recognize the color that's already been set for the calendar.
  • Timezone support is seriously lacking. For right now, known timezones exist in a static file called timezones.txt that is placed at the top of every merge output. A better implementation would aggregate timezones from calendars being merged.

About

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CalMerge

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar. Runs on a LAMP stack.

Installation

NOTE: If you don't know what a LAMP stack is, it's best to read up on that first. If you're just starting out, feel free to get in touch with me and I can try to answer any questions you have! Also note that your LAMP stack must support cURL to access external URLs and that some providers block this functionality in their basic plans.

  1. Create a new MySQL database and import the database structure found in Database/Database.sql
  2. Upload the files in the PHP folder to a directory on your server — most likely a folder that a subdomain points to.
  3. Modify PHP/config.php:
    • Add your username, password, and database name
    • Change the sharePrefix. This is the URL that users will import your calendar with and needs to correspond to the URL rewriting that goes on in .htaccess.
    • Change the name of the merged output if you desire.
  4. Modify PHP/index.php:
    • This is just a page that redirects people if they just type in the initial part of the share URL. It could redirect to your homepage or something like Google.
  5. Modify the .htaccess file. Many operating systems see this as a hidden file, so be sure that it gets uploaded. This rewrites URLs into a nicer format and restricts access to settings. You will need to create an .htpasswd file that this links to. Some providers have a built in utility to do this. In that case, it might be easiest to delete the AuthName and AuthUserFile lines and use their utility.
  6. Be sure to create an .htpasswd file that protects the files in the admin folder.

Use

  1. Navigate to admin/index.php
  2. If using a service like iCloud, create public share links of all the calendars you intend to merge.
  3. Add calendars with the "+" button in the top right of the "Calendars" panel. Each calendar should have a name, a URL, and a color (in HEX, without the pound sign).
  4. Add viewers with the "+" button in the top right of the "Viewers" panel. Each viewer gets a name and a list of Calendars that they should have read access to. Modify their access through the checkboxes that appear under their name.
  5. Note that events may take up to 48 hours to process in Google Calendar. This is because they aggressively cache subscribed calendars.

FAQs

  • Q: But isn't this a public copy of my calendar? Can't anyone access it?
    • A: Yes. In theory, anyone can access the public link that you create, though it's extremely unlikely. This utility also allows you to revoke access to certain people without destroying your whole calendar.
  • Q: Why won't Google Calendar update?
    • A: Google Calendar aggressively caches subscribed calendars and there's a 24-48 hour lag window. It's supposed to be closer to 8 hours, but I've had worse luck. I realize this isn't ideal, but there's nothing I can personally do about this. Read Google's answer here.

Known Issues / To-Dos

  • It would be great to have a color picker when adding a new calendar. Or a service that attempts to recognize the color that's already been set for the calendar.
  • Timezone support is seriously lacking. For right now, known timezones exist in a static file called timezones.txt that is placed at the top of every merge output. A better implementation would aggregate timezones from calendars being merged.

About

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CalMerge

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar. Runs on a LAMP stack.

Installation

NOTE: If you don't know what a LAMP stack is, it's best to read up on that first. If you're just starting out, feel free to get in touch with me and I can try to answer any questions you have! Also note that your LAMP stack must support cURL to access external URLs and that some providers block this functionality in their basic plans.

  1. Create a new MySQL database and import the database structure found in Database/Database.sql
  2. Upload the files in the PHP folder to a directory on your server — most likely a folder that a subdomain points to.
  3. Modify PHP/config.php:
    • Add your username, password, and database name
    • Change the sharePrefix. This is the URL that users will import your calendar with and needs to correspond to the URL rewriting that goes on in .htaccess.
    • Change the name of the merged output if you desire.
  4. Modify PHP/index.php:
    • This is just a page that redirects people if they just type in the initial part of the share URL. It could redirect to your homepage or something like Google.
  5. Modify the .htaccess file. Many operating systems see this as a hidden file, so be sure that it gets uploaded. This rewrites URLs into a nicer format and restricts access to settings. You will need to create an .htpasswd file that this links to. Some providers have a built in utility to do this. In that case, it might be easiest to delete the AuthName and AuthUserFile lines and use their utility.
  6. Be sure to create an .htpasswd file that protects the files in the admin folder.

Use

  1. Navigate to admin/index.php
  2. If using a service like iCloud, create public share links of all the calendars you intend to merge.
  3. Add calendars with the "+" button in the top right of the "Calendars" panel. Each calendar should have a name, a URL, and a color (in HEX, without the pound sign).
  4. Add viewers with the "+" button in the top right of the "Viewers" panel. Each viewer gets a name and a list of Calendars that they should have read access to. Modify their access through the checkboxes that appear under their name.
  5. Note that events may take up to 48 hours to process in Google Calendar. This is because they aggressively cache subscribed calendars.

FAQs

  • Q: But isn't this a public copy of my calendar? Can't anyone access it?
    • A: Yes. In theory, anyone can access the public link that you create, though it's extremely unlikely. This utility also allows you to revoke access to certain people without destroying your whole calendar.
  • Q: Why won't Google Calendar update?
    • A: Google Calendar aggressively caches subscribed calendars and there's a 24-48 hour lag window. It's supposed to be closer to 8 hours, but I've had worse luck. I realize this isn't ideal, but there's nothing I can personally do about this. Read Google's answer here.

Known Issues / To-Dos

  • It would be great to have a color picker when adding a new calendar. Or a service that attempts to recognize the color that's already been set for the calendar.
  • Timezone support is seriously lacking. For right now, known timezones exist in a static file called timezones.txt that is placed at the top of every merge output. A better implementation would aggregate timezones from calendars being merged.

About

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CalMerge

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar. Runs on a LAMP stack.

Installation

NOTE: If you don't know what a LAMP stack is, it's best to read up on that first. If you're just starting out, feel free to get in touch with me and I can try to answer any questions you have! Also note that your LAMP stack must support cURL to access external URLs and that some providers block this functionality in their basic plans.

  1. Create a new MySQL database and import the database structure found in Database/Database.sql
  2. Upload the files in the PHP folder to a directory on your server — most likely a folder that a subdomain points to.
  3. Modify PHP/config.php:
    • Add your username, password, and database name
    • Change the sharePrefix. This is the URL that users will import your calendar with and needs to correspond to the URL rewriting that goes on in .htaccess.
    • Change the name of the merged output if you desire.
  4. Modify PHP/index.php:
    • This is just a page that redirects people if they just type in the initial part of the share URL. It could redirect to your homepage or something like Google.
  5. Modify the .htaccess file. Many operating systems see this as a hidden file, so be sure that it gets uploaded. This rewrites URLs into a nicer format and restricts access to settings. You will need to create an .htpasswd file that this links to. Some providers have a built in utility to do this. In that case, it might be easiest to delete the AuthName and AuthUserFile lines and use their utility.
  6. Be sure to create an .htpasswd file that protects the files in the admin folder.

Use

  1. Navigate to admin/index.php
  2. If using a service like iCloud, create public share links of all the calendars you intend to merge.
  3. Add calendars with the "+" button in the top right of the "Calendars" panel. Each calendar should have a name, a URL, and a color (in HEX, without the pound sign).
  4. Add viewers with the "+" button in the top right of the "Viewers" panel. Each viewer gets a name and a list of Calendars that they should have read access to. Modify their access through the checkboxes that appear under their name.
  5. Note that events may take up to 48 hours to process in Google Calendar. This is because they aggressively cache subscribed calendars.

FAQs

  • Q: But isn't this a public copy of my calendar? Can't anyone access it?
    • A: Yes. In theory, anyone can access the public link that you create, though it's extremely unlikely. This utility also allows you to revoke access to certain people without destroying your whole calendar.
  • Q: Why won't Google Calendar update?
    • A: Google Calendar aggressively caches subscribed calendars and there's a 24-48 hour lag window. It's supposed to be closer to 8 hours, but I've had worse luck. I realize this isn't ideal, but there's nothing I can personally do about this. Read Google's answer here.

Known Issues / To-Dos

  • It would be great to have a color picker when adding a new calendar. Or a service that attempts to recognize the color that's already been set for the calendar.
  • Timezone support is seriously lacking. For right now, known timezones exist in a static file called timezones.txt that is placed at the top of every merge output. A better implementation would aggregate timezones from calendars being merged.

About

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CalMerge

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar. Runs on a LAMP stack.

Installation

NOTE: If you don't know what a LAMP stack is, it's best to read up on that first. If you're just starting out, feel free to get in touch with me and I can try to answer any questions you have! Also note that your LAMP stack must support cURL to access external URLs and that some providers block this functionality in their basic plans.

  1. Create a new MySQL database and import the database structure found in Database/Database.sql
  2. Upload the files in the PHP folder to a directory on your server — most likely a folder that a subdomain points to.
  3. Modify PHP/config.php:
    • Add your username, password, and database name
    • Change the sharePrefix. This is the URL that users will import your calendar with and needs to correspond to the URL rewriting that goes on in .htaccess.
    • Change the name of the merged output if you desire.
  4. Modify PHP/index.php:
    • This is just a page that redirects people if they just type in the initial part of the share URL. It could redirect to your homepage or something like Google.
  5. Modify the .htaccess file. Many operating systems see this as a hidden file, so be sure that it gets uploaded. This rewrites URLs into a nicer format and restricts access to settings. You will need to create an .htpasswd file that this links to. Some providers have a built in utility to do this. In that case, it might be easiest to delete the AuthName and AuthUserFile lines and use their utility.
  6. Be sure to create an .htpasswd file that protects the files in the admin folder.

Use

  1. Navigate to admin/index.php
  2. If using a service like iCloud, create public share links of all the calendars you intend to merge.
  3. Add calendars with the "+" button in the top right of the "Calendars" panel. Each calendar should have a name, a URL, and a color (in HEX, without the pound sign).
  4. Add viewers with the "+" button in the top right of the "Viewers" panel. Each viewer gets a name and a list of Calendars that they should have read access to. Modify their access through the checkboxes that appear under their name.
  5. Note that events may take up to 48 hours to process in Google Calendar. This is because they aggressively cache subscribed calendars.

FAQs

  • Q: But isn't this a public copy of my calendar? Can't anyone access it?
    • A: Yes. In theory, anyone can access the public link that you create, though it's extremely unlikely. This utility also allows you to revoke access to certain people without destroying your whole calendar.
  • Q: Why won't Google Calendar update?
    • A: Google Calendar aggressively caches subscribed calendars and there's a 24-48 hour lag window. It's supposed to be closer to 8 hours, but I've had worse luck. I realize this isn't ideal, but there's nothing I can personally do about this. Read Google's answer here.

Known Issues / To-Dos

  • It would be great to have a color picker when adding a new calendar. Or a service that attempts to recognize the color that's already been set for the calendar.
  • Timezone support is seriously lacking. For right now, known timezones exist in a static file called timezones.txt that is placed at the top of every merge output. A better implementation would aggregate timezones from calendars being merged.

About

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CalMerge

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar. Runs on a LAMP stack.

Installation

NOTE: If you don't know what a LAMP stack is, it's best to read up on that first. If you're just starting out, feel free to get in touch with me and I can try to answer any questions you have! Also note that your LAMP stack must support cURL to access external URLs and that some providers block this functionality in their basic plans.

  1. Create a new MySQL database and import the database structure found in Database/Database.sql
  2. Upload the files in the PHP folder to a directory on your server — most likely a folder that a subdomain points to.
  3. Modify PHP/config.php:
    • Add your username, password, and database name
    • Change the sharePrefix. This is the URL that users will import your calendar with and needs to correspond to the URL rewriting that goes on in .htaccess.
    • Change the name of the merged output if you desire.
  4. Modify PHP/index.php:
    • This is just a page that redirects people if they just type in the initial part of the share URL. It could redirect to your homepage or something like Google.
  5. Modify the .htaccess file. Many operating systems see this as a hidden file, so be sure that it gets uploaded. This rewrites URLs into a nicer format and restricts access to settings. You will need to create an .htpasswd file that this links to. Some providers have a built in utility to do this. In that case, it might be easiest to delete the AuthName and AuthUserFile lines and use their utility.
  6. Be sure to create an .htpasswd file that protects the files in the admin folder.

Use

  1. Navigate to admin/index.php
  2. If using a service like iCloud, create public share links of all the calendars you intend to merge.
  3. Add calendars with the "+" button in the top right of the "Calendars" panel. Each calendar should have a name, a URL, and a color (in HEX, without the pound sign).
  4. Add viewers with the "+" button in the top right of the "Viewers" panel. Each viewer gets a name and a list of Calendars that they should have read access to. Modify their access through the checkboxes that appear under their name.
  5. Note that events may take up to 48 hours to process in Google Calendar. This is because they aggressively cache subscribed calendars.

FAQs

  • Q: But isn't this a public copy of my calendar? Can't anyone access it?
    • A: Yes. In theory, anyone can access the public link that you create, though it's extremely unlikely. This utility also allows you to revoke access to certain people without destroying your whole calendar.
  • Q: Why won't Google Calendar update?
    • A: Google Calendar aggressively caches subscribed calendars and there's a 24-48 hour lag window. It's supposed to be closer to 8 hours, but I've had worse luck. I realize this isn't ideal, but there's nothing I can personally do about this. Read Google's answer here.

Known Issues / To-Dos

  • It would be great to have a color picker when adding a new calendar. Or a service that attempts to recognize the color that's already been set for the calendar.
  • Timezone support is seriously lacking. For right now, known timezones exist in a static file called timezones.txt that is placed at the top of every merge output. A better implementation would aggregate timezones from calendars being merged.

About

ICS merging and (limited) access control for public Calendars. Can also act as a proxy between iCloud and Google Calendar.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages