commit 9000ecdce5d2dfa44af651379c469c0d6bead890
Author: tanshu
Date: Sun May 24 14:09:35 2015 +0530
Initial Commit.
Gitignore ignores all PyCharm files as well as recommended python files
Basic starter project with Pyramid 1.5.x
Templates are copied from the OpenPhoto (Trovebox) files
Targets:
1. Photo management
2. Angularjs with keyboard/swipe navigation
3. Json API compatible with OpenPhoto
4. Amazon S3 support
5. Tags, etc.
6. The one true source of all a person's photos
In Greek mythology, Soter was the spirit of safety, preservation and deliverance from harm.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fd64966
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,106 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# 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/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*,cover
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion
+
+*.iml
+
+## Directory-based project format:
+.idea/
+# if you remove the above rule, at least ignore the following:
+
+# User-specific stuff:
+# .idea/workspace.xml
+# .idea/tasks.xml
+# .idea/dictionaries
+
+# Sensitive or high-churn files:
+# .idea/dataSources.ids
+# .idea/dataSources.xml
+# .idea/sqlDataSources.xml
+# .idea/dynamic.xml
+# .idea/uiDesigner.xml
+
+# Gradle:
+# .idea/gradle.xml
+# .idea/libraries
+
+# Mongo Explorer plugin:
+# .idea/mongoSettings.xml
+
+## File-based project format:
+*.ipr
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+/out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
\ No newline at end of file
diff --git a/CHANGES.txt b/CHANGES.txt
new file mode 100644
index 0000000..35a34f3
--- /dev/null
+++ b/CHANGES.txt
@@ -0,0 +1,4 @@
+0.0
+---
+
+- Initial version
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..e17f830
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,2 @@
+include *.txt *.ini *.cfg *.rst
+recursive-include soter *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..ffdd9f8
--- /dev/null
+++ b/README.txt
@@ -0,0 +1 @@
+Soter README
diff --git a/development.ini b/development.ini
new file mode 100644
index 0000000..fb6a7e0
--- /dev/null
+++ b/development.ini
@@ -0,0 +1,60 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/environment.html
+###
+
+[app:main]
+use = egg:Soter
+
+pyramid.reload_templates = true
+pyramid.debug_authorization = false
+pyramid.debug_notfound = false
+pyramid.debug_routematch = false
+pyramid.default_locale_name = en
+pyramid.includes =
+ pyramid_debugtoolbar
+
+# By default, the toolbar only appears for clients from IP addresses
+# '127.0.0.1' and '::1'.
+# debugtoolbar.hosts = 127.0.0.1 ::1
+
+###
+# wsgi server configuration
+###
+
+[server:main]
+use = egg:waitress#main
+host = 0.0.0.0
+port = 6543
+
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/logging.html
+###
+
+[loggers]
+keys = root, soter
+
+[handlers]
+keys = console
+
+[formatters]
+keys = generic
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_soter]
+level = DEBUG
+handlers =
+qualname = soter
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[formatter_generic]
+format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
diff --git a/production.ini b/production.ini
new file mode 100644
index 0000000..c55d340
--- /dev/null
+++ b/production.ini
@@ -0,0 +1,54 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/environment.html
+###
+
+[app:main]
+use = egg:Soter
+
+pyramid.reload_templates = false
+pyramid.debug_authorization = false
+pyramid.debug_notfound = false
+pyramid.debug_routematch = false
+pyramid.default_locale_name = en
+
+###
+# wsgi server configuration
+###
+
+[server:main]
+use = egg:waitress#main
+host = 0.0.0.0
+port = 6543
+
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/logging.html
+###
+
+[loggers]
+keys = root, soter
+
+[handlers]
+keys = console
+
+[formatters]
+keys = generic
+
+[logger_root]
+level = WARN
+handlers = console
+
+[logger_soter]
+level = WARN
+handlers =
+qualname = soter
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[formatter_generic]
+format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..963c2e6
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,42 @@
+import os
+
+from setuptools import setup, find_packages
+
+here = os.path.abspath(os.path.dirname(__file__))
+with open(os.path.join(here, 'README.txt')) as f:
+ README = f.read()
+with open(os.path.join(here, 'CHANGES.txt')) as f:
+ CHANGES = f.read()
+
+requires = [
+ 'pyramid',
+ 'pyramid_chameleon',
+ 'pyramid_debugtoolbar',
+ 'waitress',
+ ]
+
+setup(name='Soter',
+ version='0.0',
+ description='Soter',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ "Programming Language :: Python",
+ "Framework :: Pyramid",
+ "Topic :: Internet :: WWW/HTTP",
+ "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ install_requires=requires,
+ tests_require=requires,
+ test_suite="soter",
+ entry_points="""\
+ [paste.app_factory]
+ main = soter:main
+ """,
+ )
diff --git a/soter/__init__.py b/soter/__init__.py
new file mode 100644
index 0000000..7a20df8
--- /dev/null
+++ b/soter/__init__.py
@@ -0,0 +1,29 @@
+from pyramid.config import Configurator
+
+
+def main(global_config, **settings):
+ """ This function returns a Pyramid WSGI application.
+ """
+ config = Configurator(settings=settings)
+ config.include('pyramid_chameleon')
+ config.add_static_view('static', 'static', cache_max_age=3600)
+ config.add_route('home', '/')
+
+
+ #
+ # Hello world test endpoint.
+ # If ?auth=true is passed then it will run OAuth validation on the request.
+ #
+ config.add_route('hello', '/v{version}/hello.json')
+
+ #
+ # Action endpoints
+ # All action endpoints follow the same convention.
+ # Everything in []'s are optional
+ # /action/{id}[/{additional}].json
+ config.add_route('view', '/v{version}/action/{id}/view.json')
+ config.add_route('delete', '/v{version}/action/{id}/delete.json')
+ config.add_route('create', '/v{version}/action/{id}/create.json')
+
+ config.scan()
+ return config.make_wsgi_app()
diff --git a/soter/static/pyramid-16x16.png b/soter/static/pyramid-16x16.png
new file mode 100644
index 0000000..9792031
Binary files /dev/null and b/soter/static/pyramid-16x16.png differ
diff --git a/soter/static/pyramid.png b/soter/static/pyramid.png
new file mode 100644
index 0000000..4ab837b
Binary files /dev/null and b/soter/static/pyramid.png differ
diff --git a/soter/static/theme.css b/soter/static/theme.css
new file mode 100644
index 0000000..be50ad4
--- /dev/null
+++ b/soter/static/theme.css
@@ -0,0 +1,152 @@
+@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);
+body {
+ font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: 300;
+ color: #ffffff;
+ background: #bc2131;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: 300;
+}
+p {
+ font-weight: 300;
+}
+.font-normal {
+ font-weight: 400;
+}
+.font-semi-bold {
+ font-weight: 600;
+}
+.font-bold {
+ font-weight: 700;
+}
+.starter-template {
+ margin-top: 250px;
+}
+.starter-template .content {
+ margin-left: 10px;
+}
+.starter-template .content h1 {
+ margin-top: 10px;
+ font-size: 60px;
+}
+.starter-template .content h1 .smaller {
+ font-size: 40px;
+ color: #f2b7bd;
+}
+.starter-template .content .lead {
+ font-size: 25px;
+ color: #f2b7bd;
+}
+.starter-template .content .lead .font-normal {
+ color: #ffffff;
+}
+.starter-template .links {
+ float: right;
+ right: 0;
+ margin-top: 125px;
+}
+.starter-template .links ul {
+ display: block;
+ padding: 0;
+ margin: 0;
+}
+.starter-template .links ul li {
+ list-style: none;
+ display: inline;
+ margin: 0 10px;
+}
+.starter-template .links ul li:first-child {
+ margin-left: 0;
+}
+.starter-template .links ul li:last-child {
+ margin-right: 0;
+}
+.starter-template .links ul li.current-version {
+ color: #f2b7bd;
+ font-weight: 400;
+}
+.starter-template .links ul li a {
+ color: #ffffff;
+}
+.starter-template .links ul li a:hover {
+ text-decoration: underline;
+}
+.starter-template .links ul li .icon-muted {
+ color: #eb8b95;
+ margin-right: 5px;
+}
+.starter-template .links ul li:hover .icon-muted {
+ color: #ffffff;
+}
+.starter-template .copyright {
+ margin-top: 10px;
+ font-size: 0.9em;
+ color: #f2b7bd;
+ text-transform: lowercase;
+ float: right;
+ right: 0;
+}
+@media (max-width: 1199px) {
+ .starter-template .content h1 {
+ font-size: 45px;
+ }
+ .starter-template .content h1 .smaller {
+ font-size: 30px;
+ }
+ .starter-template .content .lead {
+ font-size: 20px;
+ }
+}
+@media (max-width: 991px) {
+ .starter-template {
+ margin-top: 0;
+ }
+ .starter-template .logo {
+ margin: 40px auto;
+ }
+ .starter-template .content {
+ margin-left: 0;
+ text-align: center;
+ }
+ .starter-template .content h1 {
+ margin-bottom: 20px;
+ }
+ .starter-template .links {
+ float: none;
+ text-align: center;
+ margin-top: 60px;
+ }
+ .starter-template .copyright {
+ float: none;
+ text-align: center;
+ }
+}
+@media (max-width: 767px) {
+ .starter-template .content h1 .smaller {
+ font-size: 25px;
+ display: block;
+ }
+ .starter-template .content .lead {
+ font-size: 16px;
+ }
+ .starter-template .links {
+ margin-top: 40px;
+ }
+ .starter-template .links ul li {
+ display: block;
+ margin: 0;
+ }
+ .starter-template .links ul li .icon-muted {
+ display: none;
+ }
+ .starter-template .copyright {
+ margin-top: 20px;
+ }
+}
diff --git a/soter/static/theme.min.css b/soter/static/theme.min.css
new file mode 100644
index 0000000..2f924bc
--- /dev/null
+++ b/soter/static/theme.min.css
@@ -0,0 +1 @@
+@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}}
\ No newline at end of file
diff --git a/soter/templates/account.html b/soter/templates/account.html
new file mode 100644
index 0000000..ff5dcf8
--- /dev/null
+++ b/soter/templates/account.html
@@ -0,0 +1,33 @@
+
+
+
+
Your Account
+
+
+
+
+ Soon your account page will allow you to update your email address, change storage providers and more.
+ For now, it's just an overview.
+
+
Your email address
+
+
+
+
+
Where are your files stored?
+
+
+
+ Storage provided by openphoto.me
+
+ In your S3 bucket (utility->safe($aws['bucket']); ?>)
+
+
+ Your Dropbox account
+
+
+ You'll be able to change this soon
+
+
+
+
\ No newline at end of file
diff --git a/soter/templates/manage-albums.html b/soter/templates/manage-albums.html
new file mode 100644
index 0000000..f0ae183
--- /dev/null
+++ b/soter/templates/manage-albums.html
@@ -0,0 +1,56 @@
+
+
+
+
What are albums?
+
+ Albums are a collection of photos. You can use them to share photos from a vacation or a child's birthday party.
+
+ They're similar to tags but have a few key differences.
+
+
The permission for who can view a photo applies even when it's in an album. If your photo is private then only you'll be able to see them in your album.
+
You can specify if an album shows up on the Albums page.
+
Albums are fixed unless you explicitly add a photo to it.
+
Add photos to an album using the edit form or on the manage photos page.
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/soter/templates/manage-group-form.html b/soter/templates/manage-group-form.html
new file mode 100644
index 0000000..2b5191e
--- /dev/null
+++ b/soter/templates/manage-group-form.html
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/soter/templates/manage-groups.html b/soter/templates/manage-groups.html
new file mode 100644
index 0000000..2b5191e
--- /dev/null
+++ b/soter/templates/manage-groups.html
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/soter/templates/manage-password-reset.html b/soter/templates/manage-password-reset.html
new file mode 100644
index 0000000..2b6d36d
--- /dev/null
+++ b/soter/templates/manage-password-reset.html
@@ -0,0 +1,18 @@
+
+
+
\ No newline at end of file
diff --git a/soter/templates/manage-photos.html b/soter/templates/manage-photos.html
new file mode 100644
index 0000000..163aadc
--- /dev/null
+++ b/soter/templates/manage-photos.html
@@ -0,0 +1,33 @@
+
+
+
Tips on updating your photos
+
+ You can easily edit title, tags, permission and licensing of your photos.
+ When you hover over a photo you'll see two icons.
+
+
The pencil icon brings up a dialog to edit that photo.
+
The checkmark queues that photo in case you wanted to update multiple photos at once.
\ No newline at end of file
diff --git a/soter/templates/manage-settings.html b/soter/templates/manage-settings.html
new file mode 100644
index 0000000..1e36d3b
--- /dev/null
+++ b/soter/templates/manage-settings.html
@@ -0,0 +1,208 @@
+
+
+
Configure your Trovebox site
+
+
+
+
+
+
+ Don't want users to download your original photos? No problem. Want to allow the same photo to be uploaded twice? You're at the right spot.
+
+
+
+
+
+
+
+
Your OAuth Applications
+
+
+
+
+ You've granted these applications access to your Trovebox account. Clicking revoke cannot be undone and you may have to reapprove the application.
+
+ If you do not, then simply close this window.
+ Apps let other programs have access to your Trovebox account.
+ You'll want to make sure that you trust the site you just came from.
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/soter/templates/photo-edit.html b/soter/templates/photo-edit.html
new file mode 100644
index 0000000..a18c4b7
--- /dev/null
+++ b/soter/templates/photo-edit.html
@@ -0,0 +1,68 @@
+
\ No newline at end of file
diff --git a/soter/templates/photo-form.html b/soter/templates/photo-form.html
new file mode 100644
index 0000000..9e0a7ad
--- /dev/null
+++ b/soter/templates/photo-form.html
@@ -0,0 +1,23 @@
+
Update your plugin: utility->safe($plugin); ?>
+
+
+
+
+
+
\ No newline at end of file
diff --git a/soter/templates/setup-dropbox.html b/soter/templates/setup-dropbox.html
new file mode 100644
index 0000000..443d07a
--- /dev/null
+++ b/soter/templates/setup-dropbox.html
@@ -0,0 +1,26 @@
+
+
Connect your Dropbox to Trovebox
+
+
+ Click here to create a Dropbox app if you haven't already.
+ IMPORTANT: make sure you select App Folder access level.
+
+
+
+
+
\ No newline at end of file
diff --git a/soter/templates/setup.html b/soter/templates/setup.html
new file mode 100644
index 0000000..a8ff8b9
--- /dev/null
+++ b/soter/templates/setup.html
@@ -0,0 +1,135 @@
+
\ No newline at end of file
diff --git a/soter/templates/template.html b/soter/templates/template.html
new file mode 100644
index 0000000..93249ad
--- /dev/null
+++ b/soter/templates/template.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+ meta('titles', $page); ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Trovebox
+
+
+
+
+
+
\ No newline at end of file
diff --git a/soter/templates/upgrade.html b/soter/templates/upgrade.html
new file mode 100644
index 0000000..34c3cc1
--- /dev/null
+++ b/soter/templates/upgrade.html
@@ -0,0 +1,20 @@
+
We need to upgrade from utility->safe($lastVersion); ?> to utility->safe($currentVersion); ?>
+
+
+ Before you start the upgrade you'll want to make sure you have a backup of your database.
+
+
+
+ $readme) { ?>
+
Notes for upgrading to utility->safe($version); ?>
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/soter/templates/upload-beta.html b/soter/templates/upload-beta.html
new file mode 100644
index 0000000..3bc5041
--- /dev/null
+++ b/soter/templates/upload-beta.html
@@ -0,0 +1,59 @@
+
\ No newline at end of file
diff --git a/soter/templates/upload-confirm.html b/soter/templates/upload-confirm.html
new file mode 100644
index 0000000..8951307
--- /dev/null
+++ b/soter/templates/upload-confirm.html
@@ -0,0 +1,59 @@
+ 0) { ?>
+
+
Your photos are finished uploading! Now what?
+
+
Your photos are finished uploading, but had problems. Now what?
+
+
+ 0) { ?>
+ of them already existed in your account.
+
+
+
+
+
+
+
+
+
+ 0) { ?>
+ utility->plural(count($failure), 'photo', false)); ?> could not be uploaded. Booo!
+
+
+
+
utility->safe($name); ?>
+
+
+
+
\ No newline at end of file
diff --git a/soter/templates/upload-token-dialog.html b/soter/templates/upload-token-dialog.html
new file mode 100644
index 0000000..577f82e
--- /dev/null
+++ b/soter/templates/upload-token-dialog.html
@@ -0,0 +1,10 @@
+
Enter your name or nickname
+
\ No newline at end of file
diff --git a/soter/templates/upload.html b/soter/templates/upload.html
new file mode 100644
index 0000000..1e8a2da
--- /dev/null
+++ b/soter/templates/upload.html
@@ -0,0 +1,76 @@
+
+