Compare commits
No commits in common. "add-django" and "master" have entirely different histories.
add-django
...
master
|
|
@ -1,9 +0,0 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"python.pythonPath": "/home/odie/.virtualenvs/social-scheduler-BIGBnu0C/bin/python"
|
||||
}
|
||||
6
Pipfile
6
Pipfile
|
|
@ -4,12 +4,8 @@ url = "https://pypi.org/simple"
|
|||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
flake8 = "*"
|
||||
autopep8 = "*"
|
||||
|
||||
[packages]
|
||||
facebook-sdk = "*"
|
||||
instagramapi = "*"
|
||||
django = "*"
|
||||
social-scheduler = {editable = true,path = "."}
|
||||
pillow = "*"
|
||||
instagramapi = "*"
|
||||
|
|
|
|||
|
|
@ -1,202 +0,0 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "e2f708932f4a52135061cf56ff125977a6e74cab2448464de0000ffdd1274ffe"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"decorator": {
|
||||
"hashes": [
|
||||
"sha256:73cbaadb8bc4e3c65fe1100773d56331a2d756cc0f5c7b9d8d5d5223fe04f600",
|
||||
"sha256:953d6bf082b100f43229cf547f4f97f97e970f5ad645ee7601d55ff87afdfe76"
|
||||
],
|
||||
"version": "==4.0.11"
|
||||
},
|
||||
"django": {
|
||||
"hashes": [
|
||||
"sha256:275bec66fd2588dd517ada59b8bfb23d4a9abc5a362349139ddda3c7ff6f5ade",
|
||||
"sha256:939652e9d34d7d53d74d5d8ef82a19e5f8bb2de75618f7e5360691b6e9667963"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.1.7"
|
||||
},
|
||||
"facebook-sdk": {
|
||||
"hashes": [
|
||||
"sha256:2e987b3e0f466a6f4ee77b935eb023dba1384134f004a2af21f1cfff7fe0806e",
|
||||
"sha256:cabcd2e69ea3d9f042919c99b353df7aa1e2be86d040121f6e9f5e63c1cf0f8d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.1.0"
|
||||
},
|
||||
"imageio": {
|
||||
"hashes": [
|
||||
"sha256:89d7692d9f513aa21665af7de94948bc1ef110d812fa66c34bfd486590d986bb"
|
||||
],
|
||||
"version": "==2.1.2"
|
||||
},
|
||||
"instagramapi": {
|
||||
"hashes": [
|
||||
"sha256:a8dfcb7bd25d8eecefacc2b872d464888535c8ee0a99c8a5b81066fdc953e64f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.0.2"
|
||||
},
|
||||
"moviepy": {
|
||||
"hashes": [
|
||||
"sha256:59d550a81ed1c9f6cf167da6d0707cea52ab250ddc2bc6d48b14ab1fc0ea4a0d",
|
||||
"sha256:c733967656fa4be4c37ec48af72b63ab2991455aa862321437a013705797c4ab"
|
||||
],
|
||||
"version": "==0.2.3.2"
|
||||
},
|
||||
"numpy": {
|
||||
"hashes": [
|
||||
"sha256:1980f8d84548d74921685f68096911585fee393975f53797614b34d4f409b6da",
|
||||
"sha256:22752cd809272671b273bb86df0f505f505a12368a3a5fc0aa811c7ece4dfd5c",
|
||||
"sha256:23cc40313036cffd5d1873ef3ce2e949bdee0646c5d6f375bf7ee4f368db2511",
|
||||
"sha256:2b0b118ff547fecabc247a2668f48f48b3b1f7d63676ebc5be7352a5fd9e85a5",
|
||||
"sha256:3a0bd1edf64f6a911427b608a894111f9fcdb25284f724016f34a84c9a3a6ea9",
|
||||
"sha256:3f25f6c7b0d000017e5ac55977a3999b0b1a74491eacb3c1aa716f0e01f6dcd1",
|
||||
"sha256:4061c79ac2230594a7419151028e808239450e676c39e58302ad296232e3c2e8",
|
||||
"sha256:560ceaa24f971ab37dede7ba030fc5d8fa173305d94365f814d9523ffd5d5916",
|
||||
"sha256:62be044cd58da2a947b7e7b2252a10b42920df9520fc3d39f5c4c70d5460b8ba",
|
||||
"sha256:6c692e3879dde0b67a9dc78f9bfb6f61c666b4562fd8619632d7043fb5b691b0",
|
||||
"sha256:6f65e37b5a331df950ef6ff03bd4136b3c0bbcf44d4b8e99135d68a537711b5a",
|
||||
"sha256:7a78cc4ddb253a55971115f8320a7ce28fd23a065fc33166d601f51760eecfa9",
|
||||
"sha256:80a41edf64a3626e729a62df7dd278474fc1726836552b67a8c6396fd7e86760",
|
||||
"sha256:893f4d75255f25a7b8516feb5766c6b63c54780323b9bd4bc51cdd7efc943c73",
|
||||
"sha256:972ea92f9c1b54cc1c1a3d8508e326c0114aaf0f34996772a30f3f52b73b942f",
|
||||
"sha256:9f1d4865436f794accdabadc57a8395bd3faa755449b4f65b88b7df65ae05f89",
|
||||
"sha256:9f4cd7832b35e736b739be03b55875706c8c3e5fe334a06210f1a61e5c2c8ca5",
|
||||
"sha256:adab43bf657488300d3aeeb8030d7f024fcc86e3a9b8848741ea2ea903e56610",
|
||||
"sha256:bd2834d496ba9b1bdda3a6cf3de4dc0d4a0e7be306335940402ec95132ad063d",
|
||||
"sha256:d20c0360940f30003a23c0adae2fe50a0a04f3e48dc05c298493b51fd6280197",
|
||||
"sha256:d3b3ed87061d2314ff3659bb73896e622252da52558f2380f12c421fbdee3d89",
|
||||
"sha256:dc235bf29a406dfda5790d01b998a1c01d7d37f449128c0b1b7d1c89a84fae8b",
|
||||
"sha256:fb3c83554f39f48f3fa3123b9c24aecf681b1c289f9334f8215c1d3c8e2f6e5b"
|
||||
],
|
||||
"version": "==1.16.2"
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:051de330a06c99d6f84bcf582960487835bcae3fc99365185dc2d4f65a390c0e",
|
||||
"sha256:0ae5289948c5e0a16574750021bd8be921c27d4e3527800dc9c2c1d2abc81bf7",
|
||||
"sha256:0b1efce03619cdbf8bcc61cfae81fcda59249a469f31c6735ea59badd4a6f58a",
|
||||
"sha256:163136e09bd1d6c6c6026b0a662976e86c58b932b964f255ff384ecc8c3cefa3",
|
||||
"sha256:18e912a6ccddf28defa196bd2021fe33600cbe5da1aa2f2e2c6df15f720b73d1",
|
||||
"sha256:24ec3dea52339a610d34401d2d53d0fb3c7fd08e34b20c95d2ad3973193591f1",
|
||||
"sha256:267f8e4c0a1d7e36e97c6a604f5b03ef58e2b81c1becb4fccecddcb37e063cc7",
|
||||
"sha256:3273a28734175feebbe4d0a4cde04d4ed20f620b9b506d26f44379d3c72304e1",
|
||||
"sha256:4c678e23006798fc8b6f4cef2eaad267d53ff4c1779bd1af8725cc11b72a63f3",
|
||||
"sha256:4d4bc2e6bb6861103ea4655d6b6f67af8e5336e7216e20fff3e18ffa95d7a055",
|
||||
"sha256:505738076350a337c1740a31646e1de09a164c62c07db3b996abdc0f9d2e50cf",
|
||||
"sha256:5233664eadfa342c639b9b9977190d64ad7aca4edc51a966394d7e08e7f38a9f",
|
||||
"sha256:5d95cb9f6cced2628f3e4de7e795e98b2659dfcc7176ab4a01a8b48c2c2f488f",
|
||||
"sha256:7eda4c737637af74bac4b23aa82ea6fbb19002552be85f0b89bc27e3a762d239",
|
||||
"sha256:801ddaa69659b36abf4694fed5aa9f61d1ecf2daaa6c92541bbbbb775d97b9fe",
|
||||
"sha256:825aa6d222ce2c2b90d34a0ea31914e141a85edefc07e17342f1d2fdf121c07c",
|
||||
"sha256:9c215442ff8249d41ff58700e91ef61d74f47dfd431a50253e1a1ca9436b0697",
|
||||
"sha256:a3d90022f2202bbb14da991f26ca7a30b7e4c62bf0f8bf9825603b22d7e87494",
|
||||
"sha256:a631fd36a9823638fe700d9225f9698fb59d049c942d322d4c09544dc2115356",
|
||||
"sha256:a6523a23a205be0fe664b6b8747a5c86d55da960d9586db039eec9f5c269c0e6",
|
||||
"sha256:a756ecf9f4b9b3ed49a680a649af45a8767ad038de39e6c030919c2f443eb000",
|
||||
"sha256:b117287a5bdc81f1bac891187275ec7e829e961b8032c9e5ff38b70fd036c78f",
|
||||
"sha256:ba04f57d1715ca5ff74bb7f8a818bf929a204b3b3c2c2826d1e1cc3b1c13398c",
|
||||
"sha256:cd878195166723f30865e05d87cbaf9421614501a4bd48792c5ed28f90fd36ca",
|
||||
"sha256:cee815cc62d136e96cf76771b9d3eb58e0777ec18ea50de5cfcede8a7c429aa8",
|
||||
"sha256:d1722b7aa4b40cf93ac3c80d3edd48bf93b9208241d166a14ad8e7a20ee1d4f3",
|
||||
"sha256:d7c1c06246b05529f9984435fc4fa5a545ea26606e7f450bdbe00c153f5aeaad",
|
||||
"sha256:e9c8066249c040efdda84793a2a669076f92a301ceabe69202446abb4c5c5ef9",
|
||||
"sha256:f227d7e574d050ff3996049e086e1f18c7bd2d067ef24131e50a1d3fe5831fbc",
|
||||
"sha256:fc9a12aad714af36cf3ad0275a96a733526571e52710319855628f476dcb144e"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.4.1"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9",
|
||||
"sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c"
|
||||
],
|
||||
"version": "==2018.9"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:545c4855cd9d7c12671444326337013766f4eea6068c3f0307fb2dc2696d580e",
|
||||
"sha256:5acf980358283faba0b897c73959cecf8b841205bb4b2ad3ef545f46eae1a133"
|
||||
],
|
||||
"version": "==2.11.1"
|
||||
},
|
||||
"requests-toolbelt": {
|
||||
"hashes": [
|
||||
"sha256:33899d4a559c3f0f5e9fbc115d337c4236febdc083755a160a4132d92fc3c91a",
|
||||
"sha256:a0432b1124e6b33151ecf694497b4808690dd94ce68c6648c1daa63b771278c4"
|
||||
],
|
||||
"version": "==0.7.0"
|
||||
},
|
||||
"social-scheduler": {
|
||||
"editable": true,
|
||||
"path": "."
|
||||
},
|
||||
"tqdm": {
|
||||
"hashes": [
|
||||
"sha256:14baa7a9ea7723d46f60de5f8c6f20e840baa7e3e193bf0d9ec5fe9103a15254",
|
||||
"sha256:1621b3476c2224045d8bd57209aab006612a46ae2cc518b4a92ad988983e4c3d"
|
||||
],
|
||||
"version": "==4.11.2"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"autopep8": {
|
||||
"hashes": [
|
||||
"sha256:33d2b5325b7e1afb4240814fe982eea3a92ebea712869bfd08b3c0393404248c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.4.3"
|
||||
},
|
||||
"entrypoints": {
|
||||
"hashes": [
|
||||
"sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19",
|
||||
"sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"
|
||||
],
|
||||
"version": "==0.3"
|
||||
},
|
||||
"flake8": {
|
||||
"hashes": [
|
||||
"sha256:859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661",
|
||||
"sha256:a796a115208f5c03b18f332f7c11729812c8c3ded6c46319c59b53efd3819da8"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.7.7"
|
||||
},
|
||||
"mccabe": {
|
||||
"hashes": [
|
||||
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
|
||||
"sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
|
||||
],
|
||||
"version": "==0.6.1"
|
||||
},
|
||||
"pycodestyle": {
|
||||
"hashes": [
|
||||
"sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56",
|
||||
"sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"
|
||||
],
|
||||
"version": "==2.5.0"
|
||||
},
|
||||
"pyflakes": {
|
||||
"hashes": [
|
||||
"sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0",
|
||||
"sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"
|
||||
],
|
||||
"version": "==2.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 47 KiB |
|
|
@ -0,0 +1,11 @@
|
|||
Metadata-Version: 1.2
|
||||
Name: social-scheduler
|
||||
Version: 0.0.1
|
||||
Summary: Posts to social media on a schedule
|
||||
Home-page: UNKNOWN
|
||||
Author: Patrick Neff
|
||||
Author-email: odie86@gmail.com
|
||||
License: BSD
|
||||
Description: UNKNOWN
|
||||
Platform: UNKNOWN
|
||||
Requires-Python: >= 3.6
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
README.md
|
||||
setup.cfg
|
||||
setup.py
|
||||
social_scheduler/__init__.py
|
||||
social_scheduler/__main__.py
|
||||
social_scheduler/main.py
|
||||
social_scheduler/scheduler.py
|
||||
social_scheduler.egg-info/PKG-INFO
|
||||
social_scheduler.egg-info/SOURCES.txt
|
||||
social_scheduler.egg-info/dependency_links.txt
|
||||
social_scheduler.egg-info/top_level.txt
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1 @@
|
|||
social_scheduler
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,15 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'web.settings')
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
"available on your PYTHONPATH environment variable? Did you "
|
||||
"forget to activate a virtual environment?"
|
||||
) from exc
|
||||
execute_from_command_line(sys.argv)
|
||||
|
|
@ -2,6 +2,6 @@ from .workers.instagram import InstagramWorker
|
|||
from .workers.facebook import FacebookWorker
|
||||
|
||||
|
||||
def run_scheduler(accounts):
|
||||
def run_scheduler():
|
||||
#facebook = FacebookWorker('', '')
|
||||
#instagram = InstagramWorker('', '')
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
from django.contrib.admin import AdminSite
|
||||
|
||||
|
||||
class SocialSchedulerAdmimSite(AdminSite):
|
||||
site_header = 'Social Scheduler'
|
||||
|
||||
|
||||
admin_site = SocialSchedulerAdmimSite(name='Social Scheduler Administration')
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from ..admin import admin_site
|
||||
|
||||
from .models import Post, Image
|
||||
|
||||
|
||||
class ImageInline(admin.TabularInline):
|
||||
model = Image
|
||||
extra = 1
|
||||
|
||||
|
||||
class PostAdmin(admin.ModelAdmin):
|
||||
fieldsets = [
|
||||
('Publikationsdatum', {'fields': ['publication_date']}),
|
||||
('Nachricht', {'fields': ['message', 'posted']}),
|
||||
]
|
||||
readonly_fields = ['posted']
|
||||
list_display = ['message', 'posted']
|
||||
inlines = [ImageInline]
|
||||
|
||||
|
||||
admin_site.register(Post, PostAdmin)
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PostsConfig(AppConfig):
|
||||
name = 'posts'
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
from datetime import datetime
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from social_scheduler.web.posts.models import Post, Image
|
||||
from social_scheduler.workers.instagram import InstagramWorker
|
||||
from social_scheduler.workers.facebook import FacebookWorker
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Post all scheduled posts.'
|
||||
|
||||
def post(self, message, images):
|
||||
self.facebook = FacebookWorker('', '')
|
||||
self.instagram = InstagramWorker('', '')
|
||||
if len(images) > 1:
|
||||
self.facebook.post_multiple(message, images)
|
||||
self.instagram.post_multiple(message, images[0:9])
|
||||
elif len(images) == 1:
|
||||
for image in images:
|
||||
self.facebook.post_single(message, image)
|
||||
self.instagram.post_single(message, image)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
posts = Post.objects.filter(
|
||||
publication_date__lte=datetime.now().astimezone(),
|
||||
posted=False)
|
||||
for post in posts:
|
||||
images = Image.objects.filter(post_id=post.id)
|
||||
imgs = {img.path.path: img.caption for img in images}
|
||||
|
||||
self.post(post.message, imgs)
|
||||
self.stdout.write(self.style.SUCCESS(post.message))
|
||||
self.stdout.write(self.style.SUCCESS(imgs))
|
||||
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
# Generated by Django 2.1.7 on 2019-03-02 13:30
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Image',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('path', models.CharField(max_length=4096)),
|
||||
('caption', models.CharField(max_length=2048)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Post',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('message', models.CharField(max_length=4096)),
|
||||
('publication_date', models.DateTimeField()),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# Generated by Django 2.1.7 on 2019-03-02 13:36
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('posts', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='image',
|
||||
name='post',
|
||||
field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='posts.Post'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 2.1.7 on 2019-03-02 14:00
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('posts', '0002_image_post'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='image',
|
||||
name='path',
|
||||
field=models.FileField(default=None, upload_to='media/'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
# Generated by Django 2.1.7 on 2019-03-02 15:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('posts', '0003_auto_20190302_1500'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='image',
|
||||
options={'verbose_name': 'Bild', 'verbose_name_plural': 'Bilder'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='post',
|
||||
options={'verbose_name': 'Post'},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='post',
|
||||
name='posted',
|
||||
field=models.BooleanField(default=False, verbose_name='Gepostet'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='image',
|
||||
name='caption',
|
||||
field=models.CharField(max_length=2048, verbose_name='Beschreibung'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='image',
|
||||
name='path',
|
||||
field=models.FileField(default=None, upload_to='media/', verbose_name='Bild'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='post',
|
||||
name='message',
|
||||
field=models.CharField(max_length=4096, verbose_name='Nachricht'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='post',
|
||||
name='publication_date',
|
||||
field=models.DateTimeField(verbose_name='Publizieren am'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 2.1.7 on 2019-03-02 15:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('posts', '0004_auto_20190302_1622'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='image',
|
||||
name='path',
|
||||
field=models.ImageField(default=None, upload_to='media/', verbose_name='Bild'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
from datetime import datetime
|
||||
from os.path import basename, join
|
||||
from uuid import uuid4
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
def change_upload_path(instance, filename):
|
||||
ext = filename.split('.')[-1]
|
||||
now = datetime.now()
|
||||
return join(str(now.year), str(now.month),
|
||||
f'{uuid4()}.{ext}')
|
||||
|
||||
|
||||
class Post(models.Model):
|
||||
message = models.CharField('Nachricht', max_length=4096)
|
||||
posted = models.BooleanField('Gepostet', default=False)
|
||||
publication_date = models.DateTimeField('Publizieren am')
|
||||
|
||||
class Meta():
|
||||
verbose_name = 'Post'
|
||||
|
||||
def __str__(self):
|
||||
date = self.publication_date.strftime('%d.%m.%Y %H:%M')
|
||||
return f'{date}: {self.message[0:50]}'
|
||||
|
||||
|
||||
class Image(models.Model):
|
||||
path = models.ImageField('Bild', upload_to=change_upload_path,
|
||||
default=None)
|
||||
caption = models.CharField('Beschreibung', max_length=2048)
|
||||
|
||||
post = models.ForeignKey(Post, on_delete=models.CASCADE, default=None)
|
||||
|
||||
class Meta():
|
||||
verbose_name = 'Bild'
|
||||
verbose_name_plural = 'Bilder'
|
||||
|
||||
def __str__(self):
|
||||
path = basename(str(self.path))
|
||||
return f'{path}: {self.caption[0:50]}'
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.index),
|
||||
]
|
||||
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
from django.shortcuts import render
|
||||
from django.http import HttpResponse
|
||||
|
||||
# Create your views here.
|
||||
|
||||
def index(request):
|
||||
return HttpResponse("Hello, World")
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
"""
|
||||
Django settings for social_scheduler.web project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 2.1.7.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/2.1/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/2.1/ref/settings/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = '$oyqqo98y5^biuhhexa7%l-8aq_kj+jv$3*+9i1^-$$gk6cp#v'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ['10.0.0.144', '127.0.0.1', 'localhost']
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'social_scheduler.web.posts',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'social_scheduler.web.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'social_scheduler.web.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{'NAME': ('django.contrib.auth.password_validation.'
|
||||
'UserAttributeSimilarityValidator')},
|
||||
{'NAME': ('django.contrib.auth.password_validation.'
|
||||
'MinimumLengthValidator')},
|
||||
{'NAME': ('django.contrib.auth.password_validation.'
|
||||
'CommonPasswordValidator')},
|
||||
{'NAME': ('django.contrib.auth.password_validation.'
|
||||
'NumericPasswordValidator')},
|
||||
]
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/2.1/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'de-de'
|
||||
|
||||
TIME_ZONE = 'Europe/Berlin'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/2.1/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
MEDIA_URL = '/media/'
|
||||
MEDIA_ROOT = 'media/'
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
"""social_scheduler_web URL Configuration
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/2.1/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from django.urls import path
|
||||
|
||||
from .admin import admin_site
|
||||
|
||||
urlpatterns = [
|
||||
path('', admin_site.urls),
|
||||
] + \
|
||||
static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + \
|
||||
static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
"""
|
||||
WSGI config for social_scheduler_web project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'social_scheduler_web.settings')
|
||||
|
||||
application = get_wsgi_application()
|
||||
Binary file not shown.
|
|
@ -1,26 +1,12 @@
|
|||
import facebook
|
||||
|
||||
from .worker import Worker
|
||||
|
||||
|
||||
class FacebookWorker(Worker):
|
||||
class FacebookWorker(object):
|
||||
def __init__(self, page_id, oauth_access_token):
|
||||
self.page_id = page_id
|
||||
self.oauth_access_token = oauth_access_token
|
||||
self.api = facebook.GraphAPI(self.oauth_access_token)
|
||||
|
||||
def post_single(self, caption, image):
|
||||
def post(self, image, caption):
|
||||
with open(image, 'rb') as photo:
|
||||
self.api.put_object(self.page_id, 'photos', message=caption,
|
||||
source=photo.read())
|
||||
|
||||
def post_multiple(self, message, images):
|
||||
ids = []
|
||||
for image, msg in images.items:
|
||||
with open(image, 'rb') as photo:
|
||||
result = self.api.put_object(self.page_id, 'photos',
|
||||
message=msg, source=photo.read(),
|
||||
published=False)
|
||||
ids.append(result['id'])
|
||||
self.api.put_object(self.page_id, 'feed', message=message,
|
||||
attached_media=ids)
|
||||
self.api.put_object(self.page_id, 'photos', message=caption, source=photo.read())
|
||||
|
|
|
|||
|
|
@ -1,21 +1,10 @@
|
|||
from InstagramAPI import InstagramAPI
|
||||
|
||||
from .worker import Worker
|
||||
|
||||
|
||||
class InstagramWorker(Worker):
|
||||
class InstagramWorker(object):
|
||||
def __init__(self, username, password):
|
||||
self.api = InstagramAPI(username, password)
|
||||
self.api.login()
|
||||
|
||||
def post_single(self, caption, image):
|
||||
def post(self, image, caption):
|
||||
self.api.uploadPhoto(image, caption)
|
||||
|
||||
def post_multiple(self, message, images):
|
||||
imgs = list()
|
||||
for image in images.keys():
|
||||
imgs.append({
|
||||
'type': 'photo',
|
||||
'file': image
|
||||
})
|
||||
self.api.uploadAlbum(imgs, caption=message)
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
class Worker(object):
|
||||
def post_single(self, caption, image):
|
||||
raise NotImplementedError('post_single has to be implemented')
|
||||
|
||||
def post_multiple(self, message, images):
|
||||
raise NotImplementedError('post_multiple has to be implemented')
|
||||
Loading…
Reference in New Issue