Permalink
Browse files

Version 0.0.1

  • Loading branch information...
1 parent 5c89550 commit 41233b394247f62adaa597a86594a74c1f1ea6db @joar committed Sep 23, 2012
Showing with 179 additions and 38 deletions.
  1. +2 −0 .gitignore
  2. +6 −0 automgtic.ini
  3. +109 −37 automgtic/__init__.py
  4. +7 −0 automgtic/config_spec.ini
  5. +23 −1 automgtic/models.py
  6. +15 −0 run.py
  7. +17 −0 setup.py
View
@@ -4,3 +4,5 @@
/lib
/local
.py[co]
+/automgtic_local.ini
+*.egg-info
View
@@ -0,0 +1,6 @@
+# WARNING: Do not edit this file directly, copy it first to automgtic_local.ini
+[automgtic]
+
+[mediagoblin]
+client_id = add yours here
+server = http://joar.pagekite.me
View
@@ -1,25 +1,123 @@
-from urllib2 import urlopen
+import logging
+import os
+import hashlib
+import json
+from urllib2 import urlopen, Request
+
+from poster.streaminghttp import register_openers
+from poster.encode import multipart_encode
from oauthlib.oauth2.draft25 import WebApplicationClient
-from automgtic.models import Config, session
+from configobj import ConfigObj
+from validate import Validator
+
+from automgtic.models import Media, session
+
+register_openers()
+
+_log = logging.getLogger(__name__)
+
+config = app_config = mg_config = {}
+
+
+def load_config():
+ global config, app_config, mg_config
+
+ configspec = ConfigObj('automgtic/config_spec.ini',
+ list_values=False,
+ _inspec=True)
+
+ if os.path.exists('automgtic_local.ini'):
+ config_path = 'automgtic_local.ini'
+ else:
+ config_path = 'automgtic.ini'
+
+ config = ConfigObj(config_path,
+ configspec=configspec,
+ interpolation='ConfigParser')
+
+ validator = Validator()
+ validation_result = config.validate(validator, preserve_errors=True)
+
+ app_config = config['automgtic']
+ mg_config = config['mediagoblin']
+
+
+load_config()
+
+_log.debug(config)
+
+
+def walk_files(directory):
+ for root, directories, files in os.walk(directory):
+ for f in files:
+ yield os.path.join(root, f)
+
+
+def upload_if_not_exist(path, digest):
+ media = Media.query.filter(Media.digest == unicode(digest)).first()
+
+ if media:
+ _log.debug('Contents of {0} already exist on the server'.format(path))
+ return
+
+ _log.info('Uploading {0}...'.format(path))
+ datagen, headers = multipart_encode({'file': open(path, 'rb')})
+
+ request = Request(mg_config['server'] + '/api/submit?access_token=' \
+ + mg_config['access_token'],
+ datagen, headers)
+ response = urlopen(request).read()
+ _log.info('Posted {0}'.format(path))
+ _log.debug('response: {0}'.format(response))
-def set_client_id(client_id):
- client_id = client_id or raw_input('Client identifier: ')
- set_config('client_id', client_id)
+ media_data = json.loads(response)
+ _log.debug('media data: {0}'.format(media_data))
+
+ media = Media(digest, os.path.split(path)[-1], json.dumps(media_data))
+
+ session.add(media)
+ session.commit()
+
+
+def run_autoupload(directory):
+ for path in walk_files(directory):
+ digest = digest_file(path)
+ _log.debug('{0} - sum: {1}'.format(
+ path,
+ digest))
+ upload_if_not_exist(path, digest)
+
+
+def digest_file(f, block_size=2 ** 20):
+ md5 = hashlib.md5()
+
+ if type(f) in [str, unicode]:
+ f = open(f, 'rb')
+
+ while True:
+ block = f.read(block_size)
+
+ if not block:
+ break
+
+ md5.update(block)
+
+ return md5.hexdigest()
def authorize():
client = get_client()
uri = client.prepare_request_uri(
- get_config('mg_server') + '/oauth/authorize',
+ mg_config['server'] + '/oauth/authorize',
redirect_uri='http://foo.example/')
- print 'Go to {0}, then paste the "?code=$CODE" $CODE part.'.format(uri)
+ print 'Go to {0}, then paste the $CODE part in "?code=$CODE" below.'.format(uri)
code = raw_input('code: ')
token_uri = client.prepare_request_uri(
- get_config('mg_server') + '/oauth/access_token',
+ mg_config['server'] + '/oauth/access_token',
code=code)
token_request = urlopen(token_uri)
@@ -29,36 +127,10 @@ def authorize():
print 'Token data: {0}'.format(token_data)
- set_config('access_token', token_data['access_token'])
+ mg_config['access_token'] = token_data['access_token']
+ config.write()
def get_client():
- client = WebApplicationClient(get_config('client_id'))
+ client = WebApplicationClient(mg_config['client_id'])
return client
-
-
-def get_config(key, default=None):
- conf = Config.query.filter(Config.key == unicode(key)).first()
-
- if not conf and not default:
- raise ValueError('{0} is not configured.'.format(key))
- elif not conf:
- return default
- else:
- return conf.value
-
-
-def set_config(key, value, checkfirst=False):
- conf = Config.query.filter(Config.key == unicode(key)).first()
-
- if checkfirst:
- if conf:
- raise NameError('{0} is already set in the configuration.'.format(key))
-
- if conf:
- conf.value = unicode(value)
- else:
- conf = Config(unicode(key), unicode(value))
- session.add(conf)
-
- session.commit()
@@ -0,0 +1,7 @@
+[automgtic]
+file_extensions = string_list(default=list("png", "jpg"))
+
+[mediagoblin]
+client_id = string(default='')
+server = string(default='')
+access_token = string(default='')
View
@@ -2,7 +2,7 @@
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
-engine = create_engine('sqlite:///automgtic.db', echo=True)
+engine = create_engine('sqlite:///automgtic.db')
Session = scoped_session(sessionmaker(bind=engine))
session = Session()
@@ -15,6 +15,7 @@ class AutomgticBase(object):
class Config(Base):
+ # TODO: Use a configuration file for the config
__tablename__ = 'core__config'
id = Column(Integer, primary_key=True)
@@ -31,3 +32,24 @@ def __repr__(self):
self.id,
self.key.decode('ascii', 'replace'),
self.value.decode('ascii', 'replace'))
+
+
+class Media(Base):
+ __tablename__ = 'core__media'
+
+ id = Column(Integer, primary_key=True)
+ digest = Column(Unicode(255), index=True, unique=True)
+ name = Column(Unicode(1024))
+ mediagoblin_data = Column(Unicode(8096))
+
+ def __init__(self, digest, name, mediagoblin_data):
+ self.digest = unicode(digest)
+ self.name = unicode(name)
+ self.mediagoblin_data = unicode(mediagoblin_data)
+
+ def __repr__(self):
+ return '<{0} #{1} {2} ({3})>'.format(
+ self.__class__.__name__,
+ self.id,
+ self.digest,
+ self.name)
View
15 run.py 100644 → 100755
@@ -1,10 +1,21 @@
+#!/usr/bin/env python
import argparse
import automgtic
+import logging
+
+root_log = logging.getLogger()
+logging.basicConfig()
+root_log.setLevel(logging.DEBUG)
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='automgtic - Autouploader for GNU MediaGoblin')
parser.add_argument(
+ 'directory',
+ type=str,
+ nargs='?',
+ )
+ parser.add_argument(
'--authorize',
const=True,
action='store_const',
@@ -17,5 +28,9 @@
args = parser.parse_args()
+ root_log.debug(args)
+
if args.authorize:
automgtic.authorize()
+ if args.run:
+ automgtic.run_autoupload(args.directory)
View
@@ -0,0 +1,17 @@
+from setuptools import setup, find_packages
+
+setup(
+ name='automgtic',
+ version='0.0.1',
+ author='Joar Wandborg',
+ author_email='joar [hex 40] wandborg [hex 2e] se',
+ url='https://github.com/jwandborg/automgtic',
+ packages=find_packages(),
+ include_package_data=True,
+ install_requires=[
+ 'setuptools',
+ 'configobj',
+ 'sqlalchemy',
+ 'simplejson',
+ 'poster'],
+ license='Apache License v2')

0 comments on commit 41233b3

Please sign in to comment.