adding latest + initial design patterns text file
This commit is contained in:
152
movieposterporndownloader/__dev/design-patterns.txt
Normal file
152
movieposterporndownloader/__dev/design-patterns.txt
Normal file
@@ -0,0 +1,152 @@
|
||||
To do : summarise the OOP principles
|
||||
|
||||
continue from pg20
|
||||
|
||||
# Encapsulation
|
||||
|
||||
## Interface
|
||||
|
||||
An interface is the public part of an object - which is open to interactions with other objects.
|
||||
|
||||
Interfaces look almost like classes, but only have methods (in other languages than python).
|
||||
|
||||
Interfaces aren't necessary in python because of multiple inheritance and duck typing. They are more used in Java where multiple inheritance isn't a thing/
|
||||
|
||||
Duck typing means that an operation does not formally specify the requirements that its operands have to meet, but just tries it out with what is given.
|
||||
|
||||
Thus, a dynamic type system as Python's always uses duck typing:
|
||||
|
||||
```python
|
||||
def f(x):
|
||||
x.Quack()
|
||||
```
|
||||
|
||||
If f gets an x supporting a Quack(), everything is fine, if not, it will crash at runtime.
|
||||
|
||||
|
||||
Interfaces can be implemented using Abstract base classes:
|
||||
|
||||
An interface is sort of like an empty muffin pan. It's a class file with a set of method definitions that have no code.
|
||||
|
||||
An implementation would be a class that depends on this interface that actually implements the methods that have been specified. If we were using abstract base clases, an implementation would be a class we create from this and write the abstract methods.
|
||||
|
||||
An abstract class is the same thing, but not all functions need to be empty. Some can have code. It's not strictly empty.
|
||||
|
||||
ABC:
|
||||
|
||||
```python
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
class AccountingSystem(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def create_purchase_invoice(self, purchase):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def create_sale_invoice(self, sale):
|
||||
log.debug('Creating sale invoice', sale)
|
||||
```
|
||||
|
||||
Create a normal subclass and override all abstract methods:
|
||||
|
||||
```python
|
||||
class GizmoAccountingSystem(AccountingSystem):
|
||||
|
||||
def create_purchase_invoice(self, purchase):
|
||||
submit_to_gizmo_purchase_service(purchase)
|
||||
|
||||
def create_sale_invoice(self, sale):
|
||||
super().create_sale_invoice(sale)
|
||||
submit_to_gizmo_sale_service(sale)
|
||||
```
|
||||
|
||||
You can optionally have common implementation in the abstract methods as in create_sale_invoice(), calling it with super() explicitly in the subclass as above.
|
||||
|
||||
Instantiation of a subclass that does not implement all the abstract methods fails:
|
||||
|
||||
```python
|
||||
class IncompleteAccountingSystem(AccountingSystem):
|
||||
pass
|
||||
```
|
||||
|
||||
Gives:
|
||||
|
||||
```
|
||||
>>> accounting = IncompleteAccountingSystem()
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
|
||||
create_purchase_invoice, create_sale_invoice
|
||||
```
|
||||
(see https://stackoverflow.com/a/51273196)
|
||||
|
||||
This means we can have a class that we only want to work with a certain type of object/class. We can create this class as an ABC and specify abstract methods. We can then create classes that implement this interface. Then, the parent class that we only want to work with a certain type will definitely work with the classes, which means we can use methods that we know will be present. See pg. 16.
|
||||
|
||||
## Encapsulation
|
||||
|
||||
Encapsulation is the ability of an object to hide parts of it state and behaviours from other objects - allowing you to expose only a limited interface to the rest of the program.
|
||||
|
||||
Encapsulating something means making it private - meaning it's only accessible from within the methods of it's own class.
|
||||
|
||||
You can also make something protected - this makes a member of a class available to subclasses as well.
|
||||
|
||||
In python this is through `_` and `__`.
|
||||
|
||||
## Polymorphism
|
||||
|
||||
Polymorphism is the ability of a program to detect the real class of an object and call its implementation, even when its real type is unknown in the current context.
|
||||
|
||||
You can think of a polymorphism as the ability of an object to pretend to be something else. This could be a class it extends or an interface it implements.
|
||||
|
||||
For example:
|
||||
|
||||
```python
|
||||
|
||||
bag = [Cat(), Dog()]
|
||||
|
||||
for animal in bag:
|
||||
animal.make_sound()
|
||||
```
|
||||
|
||||
Here Cat() and Dog() were pretending to be a generic animal. The code will try to invoke the method `make_sound()` without knowing if it exists. If it doesn't, it will raise an error.
|
||||
|
||||
# Relationships
|
||||
|
||||
## Inheritance
|
||||
|
||||
Inheritance: Class А inherits interface and implementation of class B but can extend it. Objects A can be treated as B. Class A depends on B.
|
||||
|
||||
The main benefit of inheritance is code reuse. If you need to create a new class that's only slightly different from an existing one, you don't need to repeat code. You can extend the current class by creating a subclass and adding any additional functionality into the subclass.
|
||||
|
||||
This subclass will inherit fields and methods of the superclass.
|
||||
|
||||
When you instantiate the subclass, think of it as "pulling" from the subclass, the subclass can define attributes on `self` which don't exist in it's scope, but when the subclass instantiates it will be able to use them.
|
||||
|
||||
Subclasses have the same interface as their parent class. You can't hide a method in a subclass if it was declared in the parent class.
|
||||
|
||||
If abstract methods are defined, they also have to be defined, even if they don't make sense in the subclass.
|
||||
|
||||
# Encapsulation
|
||||
|
||||
Identify the aspects of your application that vary and separate them from what stays the same.
|
||||
|
||||
The idea is to minimise the effect caused by changes.
|
||||
|
||||
You should isolate the parts of the program that vary into independent modules/components
|
||||
|
||||
This way, if a part of the code changes later on, you have protected the rest of the code from adverse affect.
|
||||
|
||||
## Encapsulation on a Method level
|
||||
|
||||
If a method is doing several things, highlight parts of it that are doing the different bits. You can then move things into other methods, and call them from within the current method.
|
||||
|
||||
E.g. if youre calculating tax on an order price, you can move this calculation step into a new method that takes a country, and returns the tax value. The original method can then call this new method to get its tax value.
|
||||
|
||||
## Encapsulation on a Class level
|
||||
|
||||
We know when a class starts to become too bloated if the intended purpose or responsability of the class is now confusing or not clear.
|
||||
|
||||
We can extract methods/variables and place them in a new class. Referencing these in the original class. It will reference the new methods and variables from the old class, meaning we have an aggregation relationship:
|
||||
|
||||
Aggregation: Object А knows about object B, and consists of B. Class A depends on B.
|
||||
57
movieposterporndownloader/__dev/structure.txt
Normal file
57
movieposterporndownloader/__dev/structure.txt
Normal file
@@ -0,0 +1,57 @@
|
||||
https://refactoring.guru/design-patterns
|
||||
https://sourcemaking.com/s
|
||||
|
||||
Can have a base class that you instantiate. It will inherit nothing, but it will have "lazy" methods that point to all the other classes you need.
|
||||
|
||||
E.g you can have a reddit instance. this instance can define a comment/redditor/submission method that point to those classes by returning the method directly. These methods take the same vars as the classes they point to.
|
||||
|
||||
This is a shortcut and prevents polluting the front facing class with a lot of inhertiances.
|
||||
|
||||
Alternatively, for methods that don't need any additional variables, or are ok with the defaults, you can define this as a instance variable in the __init__ method.
|
||||
|
||||
Either way, you're providing a facade/api for the methods behind the scenes, without needing multiple inheritance on the front facing class.
|
||||
|
||||
The classes behind the scenes can have mixins to extend their functionality, and can have a base class that they all inherit from (PRAWBase)
|
||||
|
||||
|
||||
When structuring the project:
|
||||
|
||||
1. Have a front facing class that is instantiated and where everything is done from.
|
||||
|
||||
2. This class should not have multiple inheritance
|
||||
|
||||
3. Have a final backend class that is responsible for the front end instance - it should be relatively simple, and selt a private variable for the front end instance that will be passed in.
|
||||
|
||||
3. The front facing class should provide a facade/api to the backend classes. These backend classes can use mixins (multiple mixins if necessary) to obtain extra functionality and should inherit from the backend class, making sure to pass 'self' in as an argument. This self will be set in the backend class so any future classes that dependo on it can access this same instance.
|
||||
|
||||
These backend classes (that have __init__) can use Super().__init__()
|
||||
|
||||
5. The front end class can either set an instance attribute (when you don't need to pass any attributes to these backend classes - they do not have __init__ set) or it can define a method that returns an instance of one of the backend classes that need instantiating and variables passing back.
|
||||
|
||||
The front end class should set the docstrings appropiately for these backend classes - either repeating the documentation or referencing the backend class documentation.
|
||||
|
||||
|
||||
Remember:
|
||||
|
||||
Front end class
|
||||
This should (at some point) pass 'self' back to the final backend class
|
||||
This backend class should assign this to an instance variable (self.instance)
|
||||
Backend classes can either be module functions (that depend on the final backend class - these should do some actual work)
|
||||
Or the backend classes can be mixins that provide additional functionality to the other backend classes.
|
||||
All the backend classes can access self.instance
|
||||
|
||||
Some ideas for backend classes:
|
||||
|
||||
Final backend class can be called MODULEbase
|
||||
You could have a class that creates objects
|
||||
this could
|
||||
|
||||
|
||||
to do - go through mixins in praw and write down what each one does
|
||||
map this logically to show how they can be seperated and organised to write a module using them.
|
||||
|
||||
|
||||
Break down your structure into different interfaces. Each class should represent an object not a state of an object. Any properties that your object has that are unique to that object can be defined as a method/property in that same class.
|
||||
Any shared functionality that more than one object might have should go in mixins that you inherit from. This allows you to share that functionality across different objects.
|
||||
|
||||
E.g reddit.Submission() - this is a subnission class and provides the interface to interact with submissions. This class represents a submission, it inherits from the base object (as expected), it also inherits several mixins. One of them is UserContentMixin which provides methods for comments and submissions. This mixin itself is just a combination of 7 other mixins, e.g EditableMixin, SavableMixin etc. This submission class can edit, it can save etc. so it can get this functionality from this mixin. This is also shared with comments which can do the same thing. It's a logical way of grouping things together.
|
||||
191
movieposterporndownloader/poetry.lock
generated
191
movieposterporndownloader/poetry.lock
generated
@@ -48,6 +48,37 @@ dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.int
|
||||
docs = ["sphinx", "zope.interface"]
|
||||
tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"]
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "A tool that automatically formats Python code to conform to the PEP 8 style guide"
|
||||
name = "autopep8"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "1.4.4"
|
||||
|
||||
[package.dependencies]
|
||||
pycodestyle = ">=2.4.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "The uncompromising code formatter."
|
||||
name = "black"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
version = "19.10b0"
|
||||
|
||||
[package.dependencies]
|
||||
appdirs = "*"
|
||||
attrs = ">=18.1.0"
|
||||
click = ">=6.5"
|
||||
pathspec = ">=0.6,<1"
|
||||
regex = "*"
|
||||
toml = ">=0.9.4"
|
||||
typed-ast = ">=1.4.0"
|
||||
|
||||
[package.extras]
|
||||
d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "Python package for providing Mozilla's CA Bundle."
|
||||
@@ -72,6 +103,14 @@ optional = false
|
||||
python-versions = "*"
|
||||
version = "6.0.0.2"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Composable command line interface toolkit"
|
||||
name = "click"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "7.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "An improved cmd.py for writing multi-command scripts and shells."
|
||||
@@ -108,14 +147,6 @@ optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "0.4.1"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Discover and load entry points from installed packages."
|
||||
name = "entrypoints"
|
||||
optional = false
|
||||
python-versions = ">=2.7"
|
||||
version = "0.3"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "ECMAScript parsing infrastructure for multipurpose analysis in Python"
|
||||
@@ -124,20 +155,6 @@ optional = false
|
||||
python-versions = "*"
|
||||
version = "4.0.1"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "the modular source code checker: pep8, pyflakes and co"
|
||||
name = "flake8"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "3.7.9"
|
||||
|
||||
[package.dependencies]
|
||||
entrypoints = ">=0.3.0,<0.4.0"
|
||||
mccabe = ">=0.6.0,<0.7.0"
|
||||
pycodestyle = ">=2.5.0,<2.6.0"
|
||||
pyflakes = ">=2.1.0,<2.2.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Clean single-source support for Python 3 and 2"
|
||||
@@ -203,6 +220,14 @@ version = "0.5.1"
|
||||
[package.extras]
|
||||
testing = ["docopt", "pytest (>=3.0.7)"]
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
name = "pathspec"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "0.6.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
@@ -241,6 +266,18 @@ version = "1.0.1"
|
||||
[package.dependencies]
|
||||
requests = ">=2.6.0,<3.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "A full-screen, console-based Python debugger"
|
||||
name = "pudb"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "2019.2"
|
||||
|
||||
[package.dependencies]
|
||||
pygments = ">=1.0"
|
||||
urwid = ">=1.1.1"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "library with cross-python path, ini-parsing, io, code, log facilities"
|
||||
@@ -257,6 +294,17 @@ optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "2.5.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Python docstring style checker"
|
||||
name = "pydocstyle"
|
||||
optional = false
|
||||
python-versions = ">=3.4"
|
||||
version = "4.0.1"
|
||||
|
||||
[package.dependencies]
|
||||
snowballstemmer = "*"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "passive checker of Python programs"
|
||||
@@ -265,6 +313,30 @@ optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "2.1.1"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Pygments is a syntax highlighting package written in Python."
|
||||
name = "pygments"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
version = "2.5.2"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Black plugin for the Python Language Server"
|
||||
name = "pyls-black"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "0.4.4"
|
||||
|
||||
[package.dependencies]
|
||||
black = ">=19.3b0"
|
||||
python-language-server = "*"
|
||||
toml = "*"
|
||||
|
||||
[package.extras]
|
||||
dev = ["isort", "flake8", "pytest", "mypy"]
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
@@ -325,6 +397,14 @@ rope = ["rope (>0.10.5)"]
|
||||
test = ["versioneer", "pylint", "pytest", "mock", "pytest-cov", "coverage", "numpy", "pandas", "matplotlib"]
|
||||
yapf = ["yapf"]
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Alternative regular expression module, to replace re."
|
||||
name = "regex"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "2019.11.1"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "Python HTTP for Humans."
|
||||
@@ -343,6 +423,14 @@ urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26"
|
||||
security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)"]
|
||||
socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"]
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "a python refactoring library..."
|
||||
name = "rope"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "0.14.0"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
@@ -351,6 +439,30 @@ optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
|
||||
version = "1.13.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "This package provides 26 stemmers for 25 languages generated from Snowball algorithms."
|
||||
name = "snowballstemmer"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "2.0.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Python Library for Tom's Obvious, Minimal Language"
|
||||
name = "toml"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "0.10.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "a fork of Python 2 and 3 ast modules with type comment support"
|
||||
name = "typed-ast"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "1.4.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Ultra fast JSON encoder and decoder for Python"
|
||||
@@ -383,6 +495,14 @@ brotli = ["brotlipy (>=0.6.0)"]
|
||||
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
|
||||
socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"]
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "A full-featured console (xterm et al.) user interface library"
|
||||
name = "urwid"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "2.1.0"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "WebSocket client for Python. hybi13 is supported."
|
||||
@@ -394,6 +514,14 @@ version = "0.56.0"
|
||||
[package.dependencies]
|
||||
six = "*"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "A formatter for Python code."
|
||||
name = "yapf"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "0.29.0"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
description = "Method and property caching decorators"
|
||||
@@ -406,7 +534,7 @@ version = "4.3.1"
|
||||
setuptools = "*"
|
||||
|
||||
[metadata]
|
||||
content-hash = "b3e3fb480cc63583134a5d8c51e5de91f34a91ad07e3fd6451d5009b11f4a085"
|
||||
content-hash = "5a887d16289754a5987734ee1f7ab3ff7c87bfee9c80a1fda0abaa0b78bd0b93"
|
||||
python-versions = "^3.8"
|
||||
|
||||
[metadata.hashes]
|
||||
@@ -415,15 +543,16 @@ appdirs = ["9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", "
|
||||
applib = ["735a4c2104d652d41048219581a8aa0c00b95ab5316730bda8a7d46235aaf824"]
|
||||
atomicwrites = ["03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", "75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"]
|
||||
attrs = ["08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"]
|
||||
autopep8 = ["4d8eec30cc81bc5617dbf1218201d770dc35629363547f17577c61683ccfb3ee"]
|
||||
black = ["1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b", "c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"]
|
||||
certifi = ["017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3", "25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f"]
|
||||
chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"]
|
||||
clang = ["73e3a7978edda18306a7e02881cfca3b616d02c5999f8570002f2cae8c84d6c3", "fea8d56f3f5f02f61c4c1160dbce0f4ff244b996993d35433124d4b505de8b79"]
|
||||
click = ["2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", "5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"]
|
||||
cmdln = ["9b036d89914b49f5f3166a8b3730729f17a7fb533f6a264947a8bbef016d7e20"]
|
||||
codeintel = ["00d6880539a4f8ae2e833ce1556e2c06ab04640b883203c1f2a08d9af62187c7", "0729b592c68cffcf6a73e30a585d3b42226e281c25eb1b31558c842aa498041a", "0c3d0fcd356082b0f786e52151e36e2ca8622ea399896ac5478d39e7f78815e8", "0dc9e5bb254e78ecfb4055ec596c9a4dadca1a6727577ee8d7f369cbbe40e85f", "19b823b9ba45676f6802c260ba1518ee8a632e367c8651340dd94f62a73baa33", "28e845e5360ff247541d7d88d9d775eb743852d308a8e61af3a5dcfc5fb9120d", "2cb2a29a16e06707f2ad8442d98aca1e82035010d16b39ce811dce53e9c5b683", "3768174b27e2f500bc16dff815de2403fe2c97a5672914d47956a1a3644fca88", "3b91b3bbe622e4f7afa5f17856fe0556cde0fc5cfdafb33d12bb94d1b1174674", "3c2c4b8a2599973966437628c8d8308d2ae8f0c9be4e6f111fb2ab5ee07b2984", "3c52a4cfbfa95bd5f4f436d85aa31d6d7edd97ce6c43320a94d75024abe09634", "3f35f1b0151ca6bdcab0fb4ad50c77f0715b33a111f41a852b92e8003a525067", "3f430ab1f018ec05926742e44529200d2b8424adf54d5694a7b81e3207c099aa", "48267f591a3d00e39063358d5e220038980136b9d7c93c975fc803ad3e9bf0c6", "4c49ae2cbe4ec92cf4f9db01f9494cf8301f262096fee2cf5350e37c7e45ea7c", "53327252fbee1b38adb3e7a1c244b6a49a4339e463ad4f05b19f54a6ce46a9e6", "54f2ee96b5961e7f956fecb539e6ca1ad258108d08e2082b614a7ddc8afaf8bd", "55ddf8027a73040c7244e00b61b5f05a2cfc3fa61c95107c695f3e1327315fe3", "5ce6e0874e3cca099fa77514f834f25fd077131e3188e067dba0d4ce1e922724", "5d5ea55a01ff4e1a6173b6867c78cfe1019fe13f657bd195aa65444eaa176425", "5e13e549232258013f7c2783f2fc04185a54daca33439a023687683b4d0e94ba", "684cee9edb12fbfb4dec09fb365b46276c12b9e65e7a8c0e71449634c2c2d494", "6e4fa55af48b102da85b8f955de82f22034d828e92eae4b3505f4f09f8bbb7a4", "6e623f3ae741b60b01017690daafa831f8d92e656709a493cb36f925debcfe49", "741e546cdf615f28302ad83b26ebf972da2af4c8b59ad2243f1328684ce68883", "79a48c9b0031beb84d51731f0f5e3e15a868d7dfbcb5d379ca3d8f29afd45ed5", "7e3dc9529dda548fd8549fba2fbabadb1f37368410a06eb7ab9ca7eae6d3f0be", "813ae2aeafb2c4c2d1ff6f3962eebb033cd7e10bac5465ef0897bc379c49f465", "8eceb6313e821eb27e42d56b5bf53ab06cc3d9031a93052d0958be0cc99ab7c1", "92976c06c223bc4c86df819baeb56bcd1c8af2d59958858d531392dce3630cca", "995be6ec9b07a0c08ffd8c6fc7d48bb215c7a1135f696dc6c84500620d6311bd", "a82ad9884f5dd7fe30de796d46929f4ceeaad0526a0d8bae05457d4e8d36211c", "a96719b9a70c3f4910263f1a31017fd52f9ae1af411e6763eb075bf659275c38", "b159404437b48b83c8f1480a3bf8a3d2025091b4f747e5a0b4a3c87a3a57afdc", "de58cde38f57121effa159a5b7b08be51b3444241f0e691d320a5f850d1ea5ea", "e9991a318885dc770e34f99b417f958b7718aa31df0b0447c5f067bf8119b3f8", "f155eb02d1cf9ed5fede9e6a3eb2c96012019b3eb5831e373b4e4d5209a1f60c", "f73594dae8426d51ad9b6e2f93b7b8f5892fdf56dd386c4dd84c01d556e556a8"]
|
||||
colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"]
|
||||
entrypoints = ["589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", "c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"]
|
||||
esprima = ["08db1a876d3c2910db9cfaeb83108193af5411fc3a3a66ebefacd390d21323ee"]
|
||||
flake8 = ["45681a117ecc81e870cbf1262835ae4af5e7a8b08e40b944a8a6e6b895914cfb", "49356e766643ad15072a789a20915d3c91dc89fd313ccd71802303fd67e4deca"]
|
||||
future = ["b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"]
|
||||
idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"]
|
||||
inflector = ["21add07f255a45ef83523ea73747b0651a1d680c79d0853009c4abff218d4d10"]
|
||||
@@ -431,19 +560,31 @@ jedi = ["786b6c3d80e2f06fd77162a07fed81b8baa22dde5d62896a790a331d6ac21a27", "ba8
|
||||
mccabe = ["ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"]
|
||||
more-itertools = ["53ff73f186307d9c8ef17a9600309154a6ae27f25579e80af4db8f047ba14bc2", "a0ea684c39bc4315ba7aae406596ef191fd84f873d2d2751f84d64e81a7a2d45"]
|
||||
parso = ["63854233e1fadb5da97f2744b6b24346d2750b85965e7e399bec1620232797dc", "666b0ee4a7a1220f65d367617f2cd3ffddff3e205f3f16a0284df30e774c2a9c"]
|
||||
pathspec = ["e285ccc8b0785beadd4c18e5708b12bb8fcf529a1e61215b3feff1d1e559ea5c"]
|
||||
pluggy = ["15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", "966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"]
|
||||
praw = ["2e5c98e49fe60e5308255ed147b670d350f98281f84f582df30f87de727b6de2", "cb8f85541ad4c6b10214ef9639acccfb5fed7ffee977be169b85357d2d2ea6d9"]
|
||||
prawcore = ["25dd14bf121bc0ad2ffc78e2322d9a01a516017105a5596cc21bb1e9a928b40c", "ab5558efb438aa73fc66c4178bfc809194dea3ce2addf4dec873de7e2fd2824e"]
|
||||
pudb = ["e8f0ea01b134d802872184b05bffc82af29a1eb2f9374a277434b932d68f58dc"]
|
||||
py = ["64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", "dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"]
|
||||
pycodestyle = ["95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", "e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"]
|
||||
pydocstyle = ["04c84e034ebb56eb6396c820442b8c4499ac5eb94a3bda88951ac3dc519b6058", "66aff87ffe34b1e49bff2dd03a88ce6843be2f3346b0c9814410d34987fbab59"]
|
||||
pyflakes = ["17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", "d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"]
|
||||
pygments = ["2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b", "98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe"]
|
||||
pyls-black = ["ba6364e92acfad97fb9b68928f90f5b266932e1da44ab0652606e4e91a5f4587", "d63149f53be4e1fbc6e7a99bb321cf58ae3cb46b8711c13c4f45c2081b8467da"]
|
||||
pytest = ["3f193df1cfe1d1609d4c583838bea3d532b18d6160fd3f55c9447fdca30848ec", "e246cf173c01169b9617fc07264b7b1316e78d7a650055235d6d897bc80d9660"]
|
||||
python-jsonrpc-server = ["ccc221b82e37853ed3fd3b64ca30b0562348127598b32413f70936fde82261d9"]
|
||||
python-language-server = ["e6b12c20915c70897036810d68378eede3dfafe40aa73ac4d46f5875dc857ca4"]
|
||||
regex = ["15454b37c5a278f46f7aa2d9339bda450c300617ca2fca6558d05d870245edc7", "1ad40708c255943a227e778b022c6497c129ad614bb7a2a2f916e12e8a359ee7", "5e00f65cc507d13ab4dfa92c1232d004fa202c1d43a32a13940ab8a5afe2fb96", "604dc563a02a74d70ae1f55208ddc9bfb6d9f470f6d1a5054c4bd5ae58744ab1", "720e34a539a76a1fedcebe4397290604cc2bdf6f81eca44adb9fb2ea071c0c69", "7caf47e4a9ac6ef08cabd3442cc4ca3386db141fb3c8b2a7e202d0470028e910", "7faf534c1841c09d8fefa60ccde7b9903c9b528853ecf41628689793290ca143", "b4e0406d822aa4993ac45072a584d57aa4931cf8288b5455bbf30c1d59dbad59", "c31eaf28c6fe75ea329add0022efeed249e37861c19681960f99bbc7db981fb2", "c7393597191fc2043c744db021643549061e12abe0b3ff5c429d806de7b93b66", "d2b302f8cdd82c8f48e9de749d1d17f85ce9a0f082880b9a4859f66b07037dc6", "e3d8dd0ec0ea280cf89026b0898971f5750a7bd92cb62c51af5a52abd020054a", "ec032cbfed59bd5a4b8eab943c310acfaaa81394e14f44454ad5c9eba4f24a74"]
|
||||
requests = ["11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"]
|
||||
rope = ["6b728fdc3e98a83446c27a91fc5d56808a004f8beab7a31ab1d7224cecc7d969", "c5c5a6a87f7b1a2095fb311135e2a3d1f194f5ecb96900fdd0a9100881f48aaf", "f0dcf719b63200d492b85535ebe5ea9b29e0d0b8aebeb87fe03fc1a65924fdaf"]
|
||||
six = ["1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", "30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"]
|
||||
snowballstemmer = ["209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0", "df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"]
|
||||
toml = ["229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", "235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e", "f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"]
|
||||
typed-ast = ["1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", "18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", "262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", "2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", "354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", "48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", "4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", "630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", "66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", "71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", "7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", "838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", "95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", "bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", "cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", "d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", "d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", "d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", "fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", "ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"]
|
||||
ujson = ["f66073e5506e91d204ab0c614a148d5aa938bdbf104751be66f8ad7a222f5f86"]
|
||||
update-checker = ["59cfad7f9a0ee99f95f1dfc60f55bf184937bcab46a7270341c2c33695572453", "70e39446fccf77b21192cf7a8214051fa93a636dc3b5c8b602b589d100a168b8"]
|
||||
urllib3 = ["a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293", "f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745"]
|
||||
urwid = ["0896f36060beb6bf3801cb554303fef336a79661401797551ba106d23ab4cd86"]
|
||||
websocket-client = ["1151d5fb3a62dc129164292e1227655e4bbc5dd5340a5165dfae61128ec50aa9", "1fd5520878b68b84b5748bb30e592b10d0a91529d5383f74f4964e72b297fd3a"]
|
||||
yapf = ["712e23c468506bf12cadd10169f852572ecc61b266258422d45aaf4ad7ef43de", "cad8a272c6001b3401de3278238fdc54997b6c2e56baa751788915f879a52fca"]
|
||||
"zope.cachedescriptors" = ["1f4d1a702f2ea3d177a1ffb404235551bb85560100ec88e6c98691734b1d194a", "ebf5d6768a7ef0a9e59bdc8a5416ce0e0ae2df86817bdb3b352defc410c9bf6d"]
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
[tool.poetry]
|
||||
name = "movieposterporndownloader"
|
||||
version = "0.1.0"
|
||||
version = "0.2.3"
|
||||
description = ""
|
||||
authors = ["dtomlinson <dtomlinson@panaetius.co.uk>"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.8"
|
||||
praw = "^6.4"
|
||||
rope = "^0.14.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^3.0"
|
||||
codeintel = "^2.0"
|
||||
autopep8 = "^1.4"
|
||||
McCabe = "^0.6.1"
|
||||
YAPF = "^0.29.0"
|
||||
pydocstyle = "^4.0"
|
||||
Rope = "^0.14.0"
|
||||
python-language-server = "^0.31.1"
|
||||
pycodestyle = "^2.5"
|
||||
flake8 = "^3.7"
|
||||
pudb = "^2019.2"
|
||||
pyls-black = "^0.4.4"
|
||||
pyflakes = "^2.1"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry>=0.12"]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Metadata-Version: 1.2
|
||||
Name: movieposterporndownloader
|
||||
Version: 0.1.0
|
||||
Version: 0.2.2
|
||||
Summary: UNKNOWN
|
||||
Home-page: UNKNOWN
|
||||
Author: dtomlinson
|
||||
|
||||
@@ -2,8 +2,10 @@ README.rst
|
||||
setup.py
|
||||
src/movieposterporndownloader/__init__.py
|
||||
src/movieposterporndownloader/__version__.py
|
||||
src/movieposterporndownloader/libraries.py
|
||||
src/movieposterporndownloader/reddit.py
|
||||
src/movieposterporndownloader.egg-info/PKG-INFO
|
||||
src/movieposterporndownloader.egg-info/SOURCES.txt
|
||||
src/movieposterporndownloader.egg-info/dependency_links.txt
|
||||
src/movieposterporndownloader.egg-info/requires.txt
|
||||
src/movieposterporndownloader.egg-info/top_level.txt
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1,2 @@
|
||||
__version__ = '0.1.0'
|
||||
version = '0.1.0'
|
||||
__version__ = version
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
import sys
|
||||
from typing import Callable, Sequence
|
||||
|
||||
__all__ = ['export'] # type: Sequence[str]
|
||||
|
||||
|
||||
def export(fn: callable) -> callable:
|
||||
def export(fn: Callable) -> Callable:
|
||||
"""decorator that exports a function/method/class in module and adds it to
|
||||
`__all__`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fn : callable
|
||||
a function/method/class to export
|
||||
Args:
|
||||
fn (Callable): a function/method/class to export
|
||||
|
||||
Returns
|
||||
-------
|
||||
callable
|
||||
returns the function `fn`
|
||||
Returns:
|
||||
Callable: returns the function `fn`
|
||||
"""
|
||||
mod = sys.modules[fn.__module__]
|
||||
if hasattr(mod, '__all__'):
|
||||
mod.__all__.append(fn.__name__)
|
||||
module = sys.modules[fn.__module__]
|
||||
if hasattr(module, '__all__'):
|
||||
module.__all__.append(fn.__name__) # type: ignore
|
||||
else:
|
||||
mod.__all__ = [fn.__name__]
|
||||
module.__all__ = [fn.__name__] # type: ignore
|
||||
return fn
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
from typing import List, TypeVar, Type
|
||||
from typing import List, TypeVar
|
||||
|
||||
import praw
|
||||
import praw # type: ignore
|
||||
import requests
|
||||
|
||||
# from movieposterporndownloader.__version__ import __version__ as version
|
||||
@@ -10,28 +10,57 @@ from movieposterporndownloader.libraries import export
|
||||
|
||||
__all__ = [] # type: List
|
||||
|
||||
T_subreddit_scraper = TypeVar('T_subreddit_scraper', bound="subredditScraper")
|
||||
T_subreddit_scraper = TypeVar('T_subreddit_scraper', bound="SubredditScraper")
|
||||
|
||||
|
||||
@export
|
||||
class subredditScraper(object):
|
||||
"""docstring for subredditScraper"""
|
||||
# @export
|
||||
class SubredditScraper(object):
|
||||
|
||||
def __init__(self, reddit_instance):
|
||||
super(subredditScraper, self).__init__()
|
||||
self.reddit_instance = reddit_instance
|
||||
"""Summary
|
||||
|
||||
def create_instance(
|
||||
cls: Type[T_subreddit_scraper],
|
||||
Attributes:
|
||||
reddit (praw.Reddit): Description
|
||||
"""
|
||||
|
||||
def __init__(self, reddit: praw.Reddit):
|
||||
"""Summary
|
||||
|
||||
Args:
|
||||
reddit (praw.Reddit): Description
|
||||
"""
|
||||
super(SubredditScraper, self).__init__()
|
||||
self.reddit = reddit # type: praw.Reddit
|
||||
|
||||
@classmethod
|
||||
def create_reddit_instance(
|
||||
cls,
|
||||
client_id: str,
|
||||
client_secret: str,
|
||||
user_agent: str,
|
||||
) -> T_subreddit_scraper:
|
||||
|
||||
reddit_instance = praw.Reddit(
|
||||
"""Summary
|
||||
|
||||
Args:
|
||||
client_id (str): Description
|
||||
client_secret (str): Description
|
||||
user_agent (str): Description
|
||||
"""
|
||||
reddit = praw.Reddit(
|
||||
client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
user_agent=user_agent,
|
||||
)
|
||||
|
||||
return cls(reddit_instance)
|
||||
return cls(reddit)
|
||||
|
||||
|
||||
inst = SubredditScraper.create_reddit_instance(
|
||||
client_id='yb7NnBPh4riSnw',
|
||||
client_secret='-3Z0XUXD2XCiksfX26jORG107fA',
|
||||
user_agent='mac:movieposterporndownloader:v0.1.0',
|
||||
)
|
||||
|
||||
inst.reddit.subreddits
|
||||
# praw.Reddit().subreddit()
|
||||
|
||||
SubredditScraper()
|
||||
|
||||
Reference in New Issue
Block a user