agoras-common 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
agoras/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Namespace package for agoras
3
+ __path__ = __import__('pkgutil').extend_path(__path__, __name__)
@@ -0,0 +1,45 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Please refer to AUTHORS.rst for a complete list of Copyright holders.
4
+ # Copyright (C) 2022-2026, Agoras Developers.
5
+
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
18
+ """
19
+ agoras.common
20
+ =============
21
+
22
+ Common utilities, logging, and shared constants for Agoras.
23
+
24
+ This package provides low-level utilities used throughout the Agoras ecosystem:
25
+ - Version and metadata information
26
+ - Logging infrastructure
27
+ - URL manipulation utilities
28
+ - Web scraping utilities
29
+ """
30
+
31
+ from .logger import ControlableLogger, logger
32
+ from .utils import add_url_timestamp, parse_metatags
33
+ from .version import __author__, __description__, __email__, __url__, __version__
34
+
35
+ __all__ = [
36
+ '__version__',
37
+ '__author__',
38
+ '__email__',
39
+ '__url__',
40
+ '__description__',
41
+ 'logger',
42
+ 'ControlableLogger',
43
+ 'add_url_timestamp',
44
+ 'parse_metatags',
45
+ ]
@@ -0,0 +1,134 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Please refer to AUTHORS.rst for a complete list of Copyright holders.
4
+ # Copyright (C) 2022-2026, Agoras Developers.
5
+
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
18
+ """
19
+ ``agoras.core.logger`` is the global application logging module.
20
+
21
+ All modules use the same global logging object. No messages will be emitted
22
+ until the logger is started.
23
+ """
24
+
25
+ import logging
26
+ import sys
27
+ from typing import cast
28
+
29
+ levelNames = {
30
+ 'CRITICAL': 50,
31
+ 'ERROR': 40,
32
+ 'WARN': 30,
33
+ 'WARNING': 30,
34
+ 'INFO': 20,
35
+ 'DEBUG': 10,
36
+ 'NOTSET': 0,
37
+ }
38
+
39
+
40
+ class ControlableLogger(logging.Logger):
41
+ """
42
+ This class represents a logger object that can be started and stopped.
43
+
44
+ It has a start method which allows you to specify a logging level.
45
+ The stop method halts output.
46
+ """
47
+
48
+ def __init__(self, name=''):
49
+ """
50
+ Initialize this ``ControlableLogger``.
51
+
52
+ The name defaults to the application name. Loggers with the same name
53
+ refer to the same underlying object. Names are hierarchical, e.g.
54
+ 'parent.child' defines a logger that is a descendant of 'parent'.
55
+
56
+ :param name: a string containing the logger name.
57
+ :return: a ``ControlableLogger`` instance.
58
+
59
+ .. versionadded:: 0.1.0
60
+ """
61
+ # Initializing parent class
62
+ super(ControlableLogger, self).__init__(name)
63
+
64
+ self.parent = logging.root
65
+
66
+ #: Attribute ``disabled`` (boolean): Stores the current status of the
67
+ #: logger.
68
+ self.disabled = True
69
+ self.propagate = False
70
+
71
+ #: Attribute ``formatstring`` (string): Stores the string that
72
+ #: will be used to format the logger output.
73
+ self.formatstring = '[%(levelname)s] %(message)s'
74
+
75
+ def start(self, filename=None):
76
+ """
77
+ Start logging with this logger.
78
+
79
+ Until the logger is started, no messages will be emitted. This applies
80
+ to all loggers with the same name and any child loggers.
81
+
82
+ .. versionadded:: 0.1.0
83
+ """
84
+ if self.disabled:
85
+ sh = logging.StreamHandler(sys.stdout)
86
+ sh.setFormatter(logging.Formatter(self.formatstring))
87
+ self.addHandler(sh)
88
+ if filename:
89
+ fh = logging.FileHandler(filename, mode='w')
90
+ fh.setFormatter(logging.Formatter(self.formatstring))
91
+ self.addHandler(fh)
92
+ self.disabled = False
93
+
94
+ def stop(self):
95
+ """
96
+ Stop logging with this logger.
97
+
98
+ Remove available handlers and set disabled attribute to ``True``.
99
+
100
+ .. versionadded:: 0.1.0
101
+ """
102
+ if not self.disabled:
103
+ for h in list(self.handlers):
104
+ self.removeHandler(h)
105
+ self.disabled = True
106
+
107
+ def loglevel(self, level='INFO'):
108
+ """
109
+ Set the log level for this logger.
110
+
111
+ Messages less than the given priority level will be ignored. The
112
+ default level is 'INFO', which conforms to the *nix convention that
113
+ a successful run should produce no diagnostic output. Available levels
114
+ and their suggested meanings:
115
+
116
+ * ``NOTSET``: all messages are processed.
117
+ * ``DEBUG``: output useful for developers.
118
+ * ``INFO``: trace normal program flow, especially external
119
+ interactions.
120
+ * ``WARNING``: an abnormal condition was detected that might need
121
+ attention.
122
+ * ``ERROR``: an error was detected but execution continued.
123
+ * ``CRITICAL``: an error was detected and execution was halted.
124
+
125
+ :param level: a string containing the desired logging level.
126
+
127
+ .. versionadded:: 0.1.0
128
+ """
129
+ if not self.disabled:
130
+ self.setLevel(levelNames[level])
131
+
132
+
133
+ logging.setLoggerClass(ControlableLogger)
134
+ logger = cast(ControlableLogger, logging.getLogger(__name__.split('.')[0]))
agoras/common/utils.py ADDED
@@ -0,0 +1,96 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Please refer to AUTHORS.rst for a complete list of Copyright holders.
4
+ # Copyright (C) 2022-2026, Agoras Developers.
5
+
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
18
+
19
+ """
20
+
21
+ agoras.common.utils
22
+ ===================
23
+
24
+ This module contains common and low level functions to all modules in agoras.
25
+
26
+ """
27
+
28
+
29
+ from urllib.parse import parse_qs, urlencode, urlparse
30
+
31
+ import requests
32
+ from bs4 import BeautifulSoup
33
+
34
+
35
+ def add_url_timestamp(url, timestamp):
36
+ parsed = urlparse(url)
37
+ query = dict(parse_qs(str(parsed.query)))
38
+ query['t'] = timestamp
39
+ parsed = parsed._replace(query=urlencode(query))
40
+ return parsed.geturl()
41
+
42
+
43
+ def metatag(tag):
44
+ return tag.name == "meta" \
45
+ and tag.has_attr("content") \
46
+ and (tag.has_attr("property") or tag.has_attr("name"))
47
+
48
+
49
+ def find_metatags(url, search):
50
+ found = {}
51
+
52
+ response = requests.get(url, timeout=20)
53
+
54
+ if response.status_code != 200:
55
+ return found
56
+
57
+ soup = BeautifulSoup(response.content, 'html.parser')
58
+
59
+ for target in search:
60
+ found_meta_tag = soup.find_all(metatag)
61
+
62
+ if not found_meta_tag:
63
+ continue
64
+
65
+ for meta_tag in found_meta_tag:
66
+
67
+ prop = meta_tag.get("property", "")
68
+ name = meta_tag.get("name", "")
69
+
70
+ if prop == target or name == target:
71
+ found[target] = meta_tag.get("content", "")
72
+
73
+ return found
74
+
75
+
76
+ def parse_metatags(url):
77
+
78
+ KNOWN_TAGS = [
79
+ "og:title",
80
+ "og:image",
81
+ "og:description",
82
+ "twitter:title",
83
+ "twitter:image",
84
+ "twitter:description",
85
+ ]
86
+
87
+ try:
88
+ data = find_metatags(url, KNOWN_TAGS)
89
+ except Exception:
90
+ data = {}
91
+
92
+ return {
93
+ "title": data.get("og:title", data.get("twitter:title", "")),
94
+ "image": data.get("og:image", data.get("twitter:image", "")),
95
+ "description": data.get("og:description", data.get("twitter:description", "")),
96
+ }
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Please refer to AUTHORS.rst for a complete list of Copyright holders.
4
+ # Copyright (C) 2022-2026, Agoras Developers.
5
+
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
18
+ """
19
+ agoras.common.version
20
+ =====================
21
+
22
+ Version and metadata information for Agoras.
23
+
24
+ This module serves as the single source of truth for version info
25
+ across all Agoras packages.
26
+ """
27
+
28
+ __author__ = 'Luis Alejandro Martínez Faneyth'
29
+ __email__ = 'luis@luisalejandro.org'
30
+ __version__ = '2.0.0'
31
+ __url__ = 'https://github.com/LuisAlejandro/agoras'
32
+ __description__ = (
33
+ 'A command line python utility to manage your social'
34
+ ' networks (Twitter, Facebook, Instagram, LinkedIn, Discord, '
35
+ 'YouTube, TikTok, Telegram, Threads, WhatsApp, and X)'
36
+ )
@@ -0,0 +1,79 @@
1
+ Metadata-Version: 2.4
2
+ Name: agoras-common
3
+ Version: 2.0.0
4
+ Summary: Common utilities and logging for Agoras
5
+ Home-page: https://github.com/LuisAlejandro/agoras
6
+ Author: Luis Alejandro Martínez Faneyth
7
+ Author-email: luis@luisalejandro.org
8
+ Keywords: utilities,logging,social networks
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
12
+ Classifier: Natural Language :: English
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/x-rst
21
+ Requires-Dist: requests==2.33.1
22
+ Requires-Dist: beautifulsoup4==4.14.3
23
+ Dynamic: author
24
+ Dynamic: author-email
25
+ Dynamic: classifier
26
+ Dynamic: description
27
+ Dynamic: description-content-type
28
+ Dynamic: home-page
29
+ Dynamic: keywords
30
+ Dynamic: requires-dist
31
+ Dynamic: requires-python
32
+ Dynamic: summary
33
+
34
+ agoras-common
35
+ =============
36
+
37
+ Low-level utilities, logging, and shared constants for the Agoras ecosystem.
38
+
39
+ Installation
40
+ ------------
41
+
42
+ .. code-block:: bash
43
+
44
+ pip install agoras-common
45
+
46
+ Contents
47
+ --------
48
+
49
+ - **Version Info**: ``__version__``, ``__author__``, ``__email__``, ``__url__``, ``__description__``
50
+ - **Utilities**: Helper functions for URL manipulation, metadata parsing
51
+ - **Logger**: Centralized logging configuration
52
+
53
+ Usage
54
+ -----
55
+
56
+ .. code-block:: python
57
+
58
+ from agoras.common import __version__, logger, add_url_timestamp, parse_metatags
59
+
60
+ # Version info
61
+ print(f"Agoras version: {__version__}")
62
+
63
+ # Logger
64
+ logger.start()
65
+ logger.loglevel('INFO')
66
+ logger.info("Hello from Agoras!")
67
+
68
+ # URL utilities
69
+ timestamped_url = add_url_timestamp('https://example.com', '20260110')
70
+ print(timestamped_url) # https://example.com?t=20260110
71
+
72
+ # Metatag parsing
73
+ metatags = parse_metatags('https://example.com')
74
+ print(metatags['title'], metatags['image'])
75
+
76
+ Dependencies
77
+ ------------
78
+
79
+ None (pure Python utilities)
@@ -0,0 +1,9 @@
1
+ agoras/__init__.py,sha256=BizfjbmRwkeL71J-UJWv3xvnQ0jUnmi2sSDBeere0JM,120
2
+ agoras/common/__init__.py,sha256=DwQEiKi8V0UWdQOQxEtIAke25pwvwsy8smoFeG_uSwg,1445
3
+ agoras/common/logger.py,sha256=OlHM1TPQ9-eN5P5DevhjHKiiIcEbrdsoUYqmjCrMtlA,4467
4
+ agoras/common/utils.py,sha256=Pk2Pb4mUh5PyOLw7szh89dU5FWch7-6fnaC7uCg5lBE,2532
5
+ agoras/common/version.py,sha256=SmMFDcfHAKf5Dz_vDKrKh3zcgv92x6_rPrnefRbBe08,1337
6
+ agoras_common-2.0.0.dist-info/METADATA,sha256=cTNh8SDaH3YlxUaHa-4Y_Xg_O154_G6TAffGUl7zxgs,2184
7
+ agoras_common-2.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
8
+ agoras_common-2.0.0.dist-info/top_level.txt,sha256=lpSbQnkePldQbtolks5qCcv_l_n22drGde6Jt-6ES_0,7
9
+ agoras_common-2.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ agoras