diff --git a/LICENSE b/LICENSE index 8dd4a73..1c36289 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Nick Knowles +Copyright (c) 2025 Nick Knowles Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 581776f..d76580b 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,15 @@ -# ESO Logs Python Client +# ESO Logs Python Client - Elder Scrolls Online Combat Log Analysis [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/) +[![PyPI version](https://badge.fury.io/py/esologs-python.svg)](https://pypi.org/project/esologs-python/) [![Documentation](https://readthedocs.org/projects/esologs-python/badge/?version=latest)](https://esologs-python.readthedocs.io/) [![Development Status](https://img.shields.io/badge/status-alpha-orange.svg)](https://github.com/knowlen/esologs-python) [![Tests](https://github.com/knowlen/esologs-python/actions/workflows/ci.yml/badge.svg)](https://github.com/knowlen/esologs-python/actions/workflows/ci.yml) -A comprehensive Python client library for the [ESO Logs API v2](https://www.esologs.com/v2-api-docs/eso/). This library provides both synchronous and asynchronous interfaces to access Elder Scrolls Online combat logging data, with built-in support for data transformation and analysis. +**esologs-python** is a comprehensive Python client library for the [ESO Logs API v2](https://www.esologs.com/v2-api-docs/eso/), designed for Elder Scrolls Online (ESO) players and developers who want to analyze combat logs, track performance metrics, and build tools for the ESO community. This library provides both synchronous and asynchronous interfaces to access ESO Logs data, with built-in support for data transformation and analysis. ## Project Status @@ -385,3 +386,13 @@ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file --- **Note**: This library is not officially affiliated with ESO Logs or ZeniMax Online Studios. + +## Related Projects and Resources + +- **ESO Logs**: [esologs.com](https://www.esologs.com/) - The premier Elder Scrolls Online combat logging service +- **Elder Scrolls Online**: [elderscrollsonline.com](https://www.elderscrollsonline.com/) - Official ESO website +- **Python Package Index**: [pypi.org/project/esologs-python](https://pypi.org/project/esologs-python/) + +## Search Terms + +Elder Scrolls Online API, ESO combat logs, ESO Logs Python, ESO performance analysis, Elder Scrolls Online DPS meter, ESO raid analysis, MMORPG combat analysis Python, ESO Logs API client, Elder Scrolls Online data analysis diff --git a/docs/robots.txt b/docs/robots.txt new file mode 100644 index 0000000..2f4bcfc --- /dev/null +++ b/docs/robots.txt @@ -0,0 +1,14 @@ +# Robots.txt for ESO Logs Python Documentation +# https://esologs-python.readthedocs.io/ + +User-agent: * +Allow: / + +# Sitemap location +Sitemap: https://esologs-python.readthedocs.io/sitemap.xml + +# Crawl-delay for responsible crawling +Crawl-delay: 1 + +# Allow search engines to index everything +Disallow: diff --git a/mkdocs.yml b/mkdocs.yml index e67f7b4..6bf7505 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,6 +1,8 @@ -site_name: ESO Logs Python -site_description: A comprehensive Python client library for the ESO Logs API v2 +site_name: ESO Logs Python - Elder Scrolls Online Combat Log Analysis +site_description: Python client library for ESO Logs API v2 - Analyze Elder Scrolls Online combat logs, track DPS/HPS metrics, build ESO tools. Features character rankings, report analysis, guild management. site_url: https://esologs-python.readthedocs.io/ +site_author: Nick Knowles +copyright: Copyright © 2024 - ESO Logs Python repo_url: https://github.com/knowlen/esologs-python repo_name: knowlen/esologs-python edit_uri: edit/main/docs/ @@ -148,6 +150,11 @@ plugins: - minify: minify_html: true minify_js: true + + # SEO Enhancements + - sitemap: + changefreq: weekly + priority: 0.5 minify_css: true htmlmin_opts: remove_comments: true @@ -179,6 +186,25 @@ extra: link: https://github.com/knowlen/esologs-python - icon: fontawesome/brands/python link: https://pypi.org/project/esologs-python/ + + # SEO and Social Media + meta: + - property: og:type + content: website + - property: og:title + content: ESO Logs Python - Elder Scrolls Online Combat Log Analysis + - property: og:description + content: Python client library for ESO Logs API v2. Analyze Elder Scrolls Online combat logs, track DPS/HPS metrics, and build ESO tools. + - property: og:url + content: https://esologs-python.readthedocs.io/ + - property: og:image + content: https://esologs-python.readthedocs.io/assets/logo.png + - name: twitter:card + content: summary + - name: twitter:title + content: ESO Logs Python + - name: twitter:description + content: Python client for ESO Logs API v2 - Elder Scrolls Online combat analysis # Analytics disabled - no cookies used # analytics: # provider: google @@ -199,6 +225,4 @@ extra: # telling us what you found lacking. generator: false -# Copyright -copyright: | - © 2024 esologs-python. +# Copyright already defined at top of file diff --git a/tests/docs/test_seo_links.py b/tests/docs/test_seo_links.py new file mode 100644 index 0000000..35e8424 --- /dev/null +++ b/tests/docs/test_seo_links.py @@ -0,0 +1,96 @@ +"""Test SEO-related links and metadata.""" + +import re +from pathlib import Path + + +class TestSEOLinks: + """Test that SEO-related links are valid.""" + + def test_readme_external_links(self): + """Test that all external links in README are properly formatted.""" + readme_path = Path(__file__).parent.parent.parent / "README.md" + content = readme_path.read_text() + + # Find all markdown links + link_pattern = re.compile(r"\[([^\]]+)\]\(([^)]+)\)") + links = link_pattern.findall(content) + + # Check that all links have valid format + for text, url in links: + assert text.strip(), f"Empty link text for URL: {url}" + assert url.strip(), f"Empty URL for link text: {text}" + + # Check external links start with http + # Skip anchors (#), absolute paths (/), and relative file paths + if not any( + url.startswith(prefix) for prefix in ["#", "/", "http://", "https://"] + ): + # This is likely a relative path - check it's not trying to be a URL + if "." in url and not any( + url.endswith(ext) + for ext in [".md", ".py", ".txt", ".yml", ".toml", ".json"] + ): + # Looks like a domain without protocol + raise AssertionError(f"URL missing protocol: {url}") + + def test_pypi_badge_exists(self): + """Test that PyPI version badge exists in README.""" + readme_path = Path(__file__).parent.parent.parent / "README.md" + content = readme_path.read_text() + + # Check for PyPI badge + assert ( + "badge.fury.io/py/esologs-python" in content + ), "PyPI version badge not found" + + def test_search_terms_format(self): + """Test that search terms are properly formatted with commas.""" + readme_path = Path(__file__).parent.parent.parent / "README.md" + content = readme_path.read_text() + + # Find search terms section + search_section = content.split("## Search Terms")[-1] + if search_section: + # Get the first paragraph after the heading + lines = search_section.strip().split("\n") + if len(lines) > 1: + search_terms_line = lines[1].strip() + # Check that it contains commas + assert ( + "," in search_terms_line + ), "Search terms should be comma-separated" + # Check that it contains expected keywords + assert "Elder Scrolls Online" in search_terms_line + assert "ESO" in search_terms_line + assert "Python" in search_terms_line + + def test_mkdocs_sitemap_config(self): + """Test that sitemap is configured in mkdocs.yml.""" + mkdocs_path = Path(__file__).parent.parent.parent / "mkdocs.yml" + content = mkdocs_path.read_text() + + # Check for sitemap plugin + assert "- sitemap:" in content, "Sitemap plugin not configured" + assert "changefreq:" in content, "Sitemap changefreq not configured" + + def test_mkdocs_social_meta(self): + """Test that OpenGraph meta tags are configured.""" + mkdocs_path = Path(__file__).parent.parent.parent / "mkdocs.yml" + content = mkdocs_path.read_text() + + # Check for OpenGraph tags + assert "og:title" in content, "OpenGraph title not configured" + assert "og:description" in content, "OpenGraph description not configured" + assert "og:type" in content, "OpenGraph type not configured" + assert "twitter:card" in content, "Twitter card not configured" + + def test_robots_txt_exists(self): + """Test that robots.txt exists for documentation.""" + robots_path = Path(__file__).parent.parent.parent / "docs" / "robots.txt" + assert robots_path.exists(), "robots.txt not found in docs directory" + + content = robots_path.read_text() + assert "User-agent:" in content, "User-agent directive missing" + assert "Sitemap:" in content, "Sitemap directive missing" + assert "esologs-python.readthedocs.io" in content, "Site URL missing"