diff --git a/config/social.yml b/config/social.yml index 25d2e5a..c03384c 100644 --- a/config/social.yml +++ b/config/social.yml @@ -49,13 +49,13 @@ accounts: - fa-trello freenode: - - Freenode IRC + - Freenode - TheOrangeOne - https://webchat.freenode.net/ - fa-rss atomio: - - AtomIO Slack + - Atom Slack - TheOrangeOne - https://atomio.slack.com/ - fa-slack @@ -69,14 +69,14 @@ accounts: codepen: - CodePen - TheOrangeOne - - https://codepen.io/~{0}/ + - https://codepen.io/{0}/ - fa-codepen npm: - npm - TheOrangeOne - https://www.npmjs.com/~{0}/ - - fa-file-code-io + - fa-file-code-o footer_accounts: - github diff --git a/content/pages/about.html b/content/pages/about.html index c1fe46f..fabc2d2 100644 --- a/content/pages/about.html +++ b/content/pages/about.html @@ -1,6 +1,5 @@ - - + @@ -14,36 +13,40 @@ -
+
-

Website

+

Personal Data

- My website is the culmination of all my knowledge, compiled into 1 place. It not only contains all my projects, but is itself is a project. + In the interest of privacy, there's very little personal information here.

- The site is primarily built with Pelican, a static site generator. This allows me to write nice clean, DRY content, and have it come out as clean, minified HTML. -

-

- The Javascript is built using Browserify, and the CSS is built using node-SCSS. Both are run as a build step when pelican builds. + The information that is here is eitther not personal enough to bother protecting, or has been selectively chosen as nothing bad.

-
+
-

Server

+

Accounts

- The website is hosted on part of my dedicated server from SoYouStart, running an Ubuntu Server VM with Dokku installed. + These are all the accounts I run, all to do with various things. Take a look!

-

- The prebuilt static files are served using a custom Express server, to make the site as fast and effective as possible. -

-
-
-
-
-
- View Source +
+ {% for key, account in ACCOUNTS.items() %} + + {% endfor %}
+
+ +
diff --git a/content/pages/contact.html b/content/pages/contact.html new file mode 100644 index 0000000..4b5de2c --- /dev/null +++ b/content/pages/contact.html @@ -0,0 +1,27 @@ + + + + + +
+
+

+ The fastest way to contact me is through twitter. Just tag me or send me a message and I'll respond as soon as possible! +

+
+
+
+
+

Need something more formal?

+

+ If you need to contact me in a more formal capacity, send me an email! I aim to respond to all emails within 3 days. +

+
+
+
+ +
+ diff --git a/pelicanconf.py b/pelicanconf.py index e3e5a2f..5525d61 100644 --- a/pelicanconf.py +++ b/pelicanconf.py @@ -7,6 +7,7 @@ sys.path.insert(0, os.path.realpath('./')) AUTHOR = "Jake Howard" SITENAME = "TheOrangeOne" SITEURL = "https://theorangeone.net" +CONTACT_EMAIL = "info@theorangeone.net" PATH = 'content' TIMEZONE = "Europe/London" DEFAULT_LANG = "en" @@ -111,7 +112,8 @@ JINJA_FILTERS = { "limit": filters.limit, "get_title": filters.get_title, "get_html_title": filters.get_html_title, - "get_image": filters.get_image + "get_image": filters.get_image, + "encode_text": filters.encode_text } JINJA_ENVIRONMENT = { diff --git a/plugins/filters.py b/plugins/filters.py index 402954d..d61bbfb 100644 --- a/plugins/filters.py +++ b/plugins/filters.py @@ -39,3 +39,7 @@ def get_html_title(instance): def get_image(instance): return get_attribute(instance, 'image') or (hasattr(instance, 'page') and get_attribute(instance.page, 'name')) or '' + + +def encode_text(text): + return " ".join([str(ord(c)) for c in text]) diff --git a/tests/__init__.py b/tests/__init__.py index 1b8d62f..fb9ff31 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -9,7 +9,7 @@ class TestClient: def get(self, path, JS=True): file_path = self.build_path(path) content = "".join(open(file_path).readlines()) - if path.endswith('html'): + if file_path.endswith('html'): content = BeautifulSoup(content, 'html.parser') if JS: for script in content(["noscript"]): # Remove noscript tags @@ -19,6 +19,8 @@ class TestClient: def build_path(self, path): if path.startswith('/'): path = path[1:] + if path.endswith('/'): + path += 'index.html' return os.path.join(self.output_path, path) def exists(self, path): diff --git a/tests/tests_common.py b/tests/tests_common.py index b935074..2713db2 100644 --- a/tests/tests_common.py +++ b/tests/tests_common.py @@ -96,5 +96,11 @@ class TestClientTestCase(TestCase): def test_file_exists(self): self.assertTrue(self.client.exists('index.html')) + def test_build_path_without_index(self): + self.assertEqual( + self.client.build_path('foo/'), + self.client.build_path('foo/index.html') + ) + def test_file_doesnt_exist(self): self.assertFalse(self.client.exists('foo.bar')) diff --git a/tests/tests_pages.py b/tests/tests_pages.py index 2afd2ae..a54d339 100644 --- a/tests/tests_pages.py +++ b/tests/tests_pages.py @@ -1,5 +1,6 @@ from tests import TestCase from config import social as social_settings +import pelicanconf as settings import os.path @@ -47,18 +48,6 @@ class AboutPageTestCase(TestCase): self.assertHeaderTitle(content, 'About') self.assertTitle(content, 'About') - def test_website_section(self): - content = self.client.get('about/index.html') - section = content.find('section', id='website') - subtitle = section.find('h2') - self.assertEqual('Website', self.get_children(subtitle)) - - def test_server_section(self): - content = self.client.get('about/index.html') - section = content.find('section', id='server') - subtitle = section.find('h2') - self.assertEqual('Server', self.get_children(subtitle)) - def test_github_card(self): content = self.client.get('about/index.html') tags = content.find_all('div', class_='github-card') @@ -67,6 +56,33 @@ class AboutPageTestCase(TestCase): self.assertEqual('medium', tag.attrs['data-theme']) self.assertEqual(social_settings['accounts']['github'][1], tag.attrs['data-github']) + def test_accounts(self): + content = self.client.get('about/index.html') + accounts = content.find_all('div', class_='account') + defined_accounts = [s for k, s in settings.ACCOUNTS.items()] + self.assertEqual(len(accounts), len(defined_accounts)) + site_names = [s['site'] for s in defined_accounts] + urls = [s['url'] for s in defined_accounts] + icons = [s['icon'] for s in defined_accounts] + for account in accounts: + self.assertIn(account.find('a').attrs['href'], urls) + self.assertIn(account.find('i').attrs['class'][-1], icons) + self.assertIn(self.get_children(account.find('h3')), site_names) + + +class ContactPageTestCase(TestCase): + def test_title(self): + content = self.client.get('contact/') + self.assertHeaderTitle(content, 'Contact Me') + self.assertTitle(content, 'Contact Me') + + def test_contact_links(self): + content = self.client.get('contact/') + links = content.find_all('section')[2].find_all('a') + self.assertEqual(links[1].attrs['href'], settings.ACCOUNTS['twitter']['url']) + decoded_value = ''.join([chr(int(c)) for c in links[0].attrs['data-value'].split(' ')]) + self.assertEqual(decoded_value, settings.CONTACT_EMAIL) + class Page404TestCase(TestCase): def test_title(self): diff --git a/theme/static/src/js/app.js b/theme/static/src/js/app.js index df81682..3b86b80 100644 --- a/theme/static/src/js/app.js +++ b/theme/static/src/js/app.js @@ -30,3 +30,14 @@ $('.navbar-brand').bind('click', function (event) { } event.preventDefault(); }); + + +$('.protected-mailto').bind('click', function (evt) { + evt.preventDefault(); + var char_codes = $(this).data('value').split(' '); + var plain_text = []; + for (var i = 0; i < char_codes.length; i++) { + plain_text.push(String.fromCharCode(parseInt(char_codes[i], 10))); + } + window.location = 'mailto:' + plain_text.join(''); +}); diff --git a/theme/static/src/scss/functional.scss b/theme/static/src/scss/functional.scss index 58c9665..3d4f6a2 100644 --- a/theme/static/src/scss/functional.scss +++ b/theme/static/src/scss/functional.scss @@ -16,3 +16,7 @@ padding: 0 $grid-gutter-width / 2; } + +a.no-underline:hover { + text-decoration: inherit; +} diff --git a/theme/static/src/scss/index.scss b/theme/static/src/scss/index.scss index 1b958f4..48f3735 100644 --- a/theme/static/src/scss/index.scss +++ b/theme/static/src/scss/index.scss @@ -110,3 +110,13 @@ header#header { .github-card-container > iframe { max-width: 100%; } + +.protected-mailto { + cursor: pointer; +} + +.service-box.account { + a:hover { + color: $brand-orange-dark; + } +}