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.
This commit is contained in:
tanshu 2015-05-24 14:09:35 +05:30
commit 9000ecdce5
33 changed files with 1455 additions and 0 deletions

106
.gitignore vendored Normal file
View File

@ -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

4
CHANGES.txt Normal file
View File

@ -0,0 +1,4 @@
0.0
---
- Initial version

2
MANIFEST.in Normal file
View File

@ -0,0 +1,2 @@
include *.txt *.ini *.cfg *.rst
recursive-include soter *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml

1
README.txt Normal file
View File

@ -0,0 +1 @@
Soter README

60
development.ini Normal file
View File

@ -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

54
production.ini Normal file
View File

@ -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

42
setup.py Normal file
View File

@ -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
""",
)

29
soter/__init__.py Normal file
View File

@ -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()

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
soter/static/pyramid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

152
soter/static/theme.css Normal file
View File

@ -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;
}
}

1
soter/static/theme.min.css vendored Normal file
View File

@ -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}}

View File

@ -0,0 +1,33 @@
<div class="account">
<?php echo $navigation; ?>
<h2>Your Account</h2>
<div class="row hero-unit blurb">
<br>
<p>
Soon your account page will allow you to update your email address, change storage providers and more.
For now, it's just an overview.
</p>
<h3>Your email address</h3>
<div class="inset">
<?php echo $email; ?>
</div>
<br>
<h3>Where are your files stored?</h3>
<div class="inset">
<?php if($systems['FileSystem'] === 'S3') { ?>
<?php if($aws['bucket'] === 'awesomeness.openphoto.me') { ?>
Storage provided by openphoto.me
<?php } else { ?>
In your S3 bucket (<?php $this->utility->safe($aws['bucket']); ?>)
<?php } ?>
<?php } elseif($systems['FileSystem'] === 'S3Dropbox') { ?>
Your Dropbox account
<?php } ?>
<div>
<em>You'll be able to change this soon</em>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,56 @@
<div class="manage albums">
<div class="row hero-unit blurb">
<h2>What are albums?</h2>
<p>
Albums are a collection of photos. You can use them to share photos from a vacation or a child's birthday party.
<br>
They're similar to tags but have a few key differences.
<ol>
<li>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.</li>
<li>You can specify if an album shows up on the <em>Albums</em> page.</li>
<li>Albums are fixed unless you explicitly add a photo to it.</li>
<li>Add photos to an album using the edit form or on the <a href="<?php $this->url->managePhotos(); ?>">manage photos</a> page.</li>
</ol>
</p>
</div>
<?php echo $albumAddForm; ?>
<?php foreach($albums as $album) { ?>
<a name="album-<?php $this->utility->safe($album['id']); ?>"></a>
<form class="well album-post-submit" action="/album/<?php $this->utility->safe($album['id']); ?>/update">
<h3>
Edit <?php $this->utility->safe($album['name']); ?>
<small>
(
<?php if($album['count'] > 0) { ?>
<a href="<?php $this->url->managePhotos(); ?>?album=<?php $this->utility->safe($album['id']); ?>"><?php $this->utility->safe($album['count']); ?> photos</a>
<?php } else{ ?>
No photos in this album
<?php } ?>
)
</small>
</h3>
<label>Name</label>
<input type="text" name="name" value="<?php $this->utility->safe($album['name']); ?>">
<div class="control-group">
<label class="control-label">Include on Albums page</label>
<div class="controls">
<label class="radio inline">
<input type="radio" name="visible" value="1" <?php if($album['visible'] == 1 || $album['visible'] == '') { ?> checked="checked" <?php } ?>>
Public
</label>
<label class="radio inline">
<input type="radio" name="visible" value="0" <?php if($album['visible'] == 0) { ?> checked="checked" <?php } ?>>
Private
</label>
</div>
</div>
<br>
<button class="btn"><i class="icon-save icon-large"></i> Save</button>&nbsp;&nbsp;&nbsp;<a class="album-delete-click" href="/album/<?php $this->utility->safe($album['id']); ?>/delete">Or delete</a>
</form>
<?php } ?>
</div>

View File

@ -0,0 +1,12 @@
<form class="<?php if(!isset($_GET['modal'])) { ?>well <?php } ?>group-post-submit" action="/group/create">
<?php if(!isset($_GET['modal'])) { ?><h3>Create a new group</h3><?php } ?>
<label>Name</label>
<input type="text" name="name">
<label>Add an email address</label>
<input type="text" class="group-email-input">&nbsp;&nbsp;&nbsp;<a href="#" class="group-email-add-click">Add</a>
<ul class="group-emails-add-list unstyled">
</ul>
<input type="hidden" name="dynamic" value="<?php if(isset($_GET['dynamic'])) { ?>1<?php } else { ?>0<?php } ?>">
<button class="btn btn-primary"><i class="icon-save icon-large"></i> Create</button>
</form>

View File

@ -0,0 +1,12 @@
<form class="<?php if(!isset($_GET['modal'])) { ?>well <?php } ?>group-post-submit" action="/group/create">
<?php if(!isset($_GET['modal'])) { ?><h3>Create a new group</h3><?php } ?>
<label>Name</label>
<input type="text" name="name">
<label>Add an email address</label>
<input type="text" class="group-email-input">&nbsp;&nbsp;&nbsp;<a href="#" class="group-email-add-click">Add</a>
<ul class="group-emails-add-list unstyled">
</ul>
<input type="hidden" name="dynamic" value="<?php if(isset($_GET['dynamic'])) { ?>1<?php } else { ?>0<?php } ?>">
<button class="btn btn-primary"><i class="icon-save icon-large"></i> Create</button>
</form>

View File

@ -0,0 +1,18 @@
<div class="manage password">
<form class="well" method="post">
<h2>So you forgot your password, huh?</h2>
<p>
No problem. Fill out the form below to reset it.
</p>
<label>New password</label>
<input type="password" name="password" class="input-password">
<label>Confirm new password</label>
<input type="password" name="password-confirm" class="input-password-confirm">
<br>
<button type="button" class="btn btn-primary manage-password-reset-click">Update my password</button>
<input type="hidden" name="token" value="<?php $this->utility->safe($passwordToken); ?>">
</form>
</div>

View File

@ -0,0 +1,33 @@
<div class="manage photos">
<div class="row hero-unit blurb">
<h2>Tips on updating your photos</h2>
<p>
You can easily edit title, tags, permission and licensing of your photos.
When you hover over a photo you'll see two icons.
<ol>
<li>The <i class="icon-edit icon-large"></i> <em>pencil</em> icon brings up a dialog to edit that photo.</li>
<li>The <i class="icon-ok icon-large"></i> <em>checkmark</em> queues that photo in case you wanted to update multiple photos at once.</li>
</ol>
</p>
</div>
<?php echo $pagination; ?>
<div class="row hero-unit empty">
<?php if($photos[0]['totalRows'] > 0) { ?>
<ul class="thumbnails">
<?php foreach($photos as $photo) { ?>
<li class="span2">
<img src="<?php $this->utility->safe($photo['path160x160']); ?>" style="width:<?php $this->utility->safe($photo['photo160x160'][1]); ?>px; <?php if($photo['photo160x160'][2] < 160) { ?> margin: <?php echo intval((160-$photo['photo160x160'][2])/2); ?>px auto;<?php } ?>" alt="<?php $this->utility->safe($photo['title']); ?>">
<div>
<i class="icon-ok icon-large photo-<?php $this->utility->safe($photo['id']); ?> pin-click pin reveal" data-id="<?php $this->utility->safe($photo['id']); ?>"></i>
<i class="icon-edit icon-large photo-<?php $this->utility->safe($photo['id']); ?> photo-edit-click edit reveal" data-id="<?php $this->utility->safe($photo['id']); ?>"></i>
</div>
</li>
<?php } ?>
</ul>
</div>
<?php } else { ?>
<?php $this->theme->display('partials/no-content.php'); ?>
<?php } ?>
</div>

View File

@ -0,0 +1,208 @@
<div class="row">
<div class="span12">
<h1>Configure your Trovebox site</h1>
</div>
</div>
<a name="settings"></a>
<div class="row">
<div class="span6">
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.
</div>
</div>
<form method="post" action="/manage/settings">
<div class="row">
<div class="span12">
<h3>General settings</h3>
<div class="controls">
<label class="checkbox inline">
<input type="checkbox" name="enableBetaFeatures" value="1" <?php if($enableBetaFeatures) { ?>checked="checked"<?php } ?>>
Enable beta features on this site and on the mobile apps
</label>
</div>
<div class="controls">
<label class="checkbox inline">
<input type="checkbox" name="allowDuplicate" value="1" <?php if($allowDuplicate) { ?>checked="checked"<?php } ?>>
The same photo can be uploaded more than once
</label>
</div>
<div class="controls">
<label class="checkbox inline">
<input type="checkbox" name="downloadOriginal" value="1" <?php if($downloadOriginal) { ?>checked="checked"<?php } ?>>
Let visitors download my original hi-res photos
</label>
</div>
<div class="controls">
<label class="checkbox inline">
<input type="checkbox" name="hideFromSearchEngines" value="1" <?php if($hideFromSearchEngines) { ?>checked="checked"<?php } ?>>
Hide my site from search engines
</label>
</div>
<div class="controls">
<label class="checkbox inline">
<input type="checkbox" name="decreaseLocationPrecision" value="1" <?php if($decreaseLocationPrecision) { ?>checked="checked"<?php } ?>>
Decrease the accuracy when displaying my photos on a map for others
</label>
</div>
</div>
<div class="span6">
<a name="admins"></a>
<h5>Collaborators</h5>
<p>
Enter email addresses for others you'd like to collaborate with you. These users will have full access to your account. They can log in using Mozilla Persona.
</p>
<div class="controls">
<?php for($i=0; $i<4; $i++) { ?>
<input type="text" name="admins[<?php echo $i; ?>]" <?php if(isset($admins[$i])) { ?> value="<?php $this->utility->safe($admins[$i]); ?>" <?php } ?> placeholder="user<?php echo ($i+1); ?>@example.com">
<?php } ?>
</div>
<div class="btn-toolbar"><button class="btn btn-brand">Save</button></div>
</div>
</div>
<input type="hidden" name="crumb" value="<?php $this->utility->safe($crumb); ?>">
</form>
<a name="apps"></a>
<div class="row">
<div class="span12">
<h3>Your OAuth Applications</h3>
</div>
</div>
<div class="row">
<div class="span6">
You've granted these applications access to your Trovebox account. Clicking <strong>revoke</strong> cannot be undone and you may have to reapprove the application.
</div>
</div>
<div class="row">
<div class="span12">
<p>
<a href="/v1/oauth/authorize?oauth_callback=<?php $this->utility->safe(sprintf('%s://%s%s', $this->utility->getProtocol(false), $_SERVER['HTTP_HOST'], '/manage/apps/callback')); ?>&name=<?php $this->utility->safe(urlencode('Self Generated App')); ?>&tokenType=access" class="btn btn-brand">Create a new app</a>
</p>
<?php if(!empty($credentials)) { ?>
<table class="table table-striped">
<thead>
<tr>
<th>Application Name</th>
<th></th>
</tr>
</thead>
<?php foreach($credentials as $credential) { ?>
<tr>
<td>
<?php $this->utility->safe($credential['name']); ?>
<?php if(!empty($credential['dateCreated'])) { ?>
<small><em class="credential-date">(<?php $this->utility->safe(ucwords($credential['type'])); ?> token created on <?php $this->utility->dateLong($credential['dateCreated']); ?>)</em></small>
<?php } ?>
</td>
<td>
<div class="pull-right">
<a href="/v1/oauth/<?php $this->utility->safe($credential['id']); ?>/markup" class="credentialView"><i class="icon-eye-open icon-large"></i> View</a>
&nbsp; &nbsp; &nbsp;
<a href="/oauth/<?php $this->utility->safe($credential['id']); ?>/delete" class="credentialDelete"><i class="icon-trash icon-large"></i> Revoke</a>
</div>
</td>
</tr>
<?php } ?>
</table>
<?php } ?>
</div>
</div>
<a name="plugins"></a>
<div class="row">
<div class="span12">
<h2>Your plugins</h2>
</div>
</div>
<div class="row">
<div class="span6">
Plugins help you add more features to your Trovebox site. Below is a list of all the available plugins you can activate and configure.
</div>
</div>
<div class="row">
<div class="span12">
<table class="table table-striped">
<thead>
<tr>
<th>Plugin Name</th>
<th></th>
</tr>
</thead>
<?php foreach($plugins as $plugin) { ?>
<tr>
<td><?php $this->utility->safe($plugin['name']); ?></td>
<td>
<div class="pull-right">
<div class="<?php if($plugin['status'] === 'inactive') { ?>hide <?php } ?>active"><i class="icon-check icon-large"></i> Active (<a href="/plugin/<?php $this->utility->safe($plugin['name']); ?>/view" class="pluginView">Configure</a> or <a href="/plugin/<?php $this->utility->safe($plugin['name']); ?>/deactivate" class="pluginStatusToggle">Deactivate</a>)</div>
<div class="<?php if($plugin['status'] === 'active') { ?>hide <?php } ?>inactive"><i class="icon-check-empty icon-large"></i> Inactive (<a href="/plugin/<?php $this->utility->safe($plugin['name']); ?>/activate" class="pluginStatusToggle">Activate</a>)</div>
</div>
</td>
</tr>
<?php } ?>
</table>
</div>
</div>
<a name="tokens"></a>
<div class="row">
<div class="span12">
<h2>Your sharing tokens</h2>
</div>
</div>
<div class="row">
<div class="span12">
<table class="table table-striped">
<thead>
<tr>
<th colspan="2">Photos</th>
</tr>
</thead>
<?php if(count($tokens['photos']) === 0) { ?>
<tr><td colspan="2">You don't have any sharing tokens for your photos.</td></tr>
<?php } else { ?>
<?php foreach($tokens['photos'] as $photo) { ?>
<tr>
<td>
Photo <?php $this->utility->safe($photo['data']); ?>
<small><em>(<?php if(empty($photo['dateExpires'])) { ?>Sharing token never expires<?php } else { ?>Sharing token expires on <?php $this->utility->dateLong($photo['dateExpires']); ?><?php } ?>)</em></small>
</td>
<td>
<div class="pull-right">
<a href="<?php $this->url->photoView($photo['data']); ?>"><i class="icon-eye-open icon-large"></i> View</a>
&nbsp; &nbsp; &nbsp;
<a href="/token/<?php $this->utility->safe($photo['id']); ?>/delete" class="tokenDelete"><i class="icon-trash icon-large"></i> Delete</a>
</div>
</td>
</tr>
<?php } ?>
<?php } ?>
</table>
<table class="table table-striped">
<thead>
<tr>
<th colspan="2">Albums</th>
</tr>
</thead>
<?php if(count($tokens['albums']) === 0) { ?>
<tr><td colspan="2">You don't have any sharing tokens for your albums.</td></tr>
<?php } else { ?>
<?php foreach($tokens['albums'] as $album) { ?>
<tr>
<td>
Album
<small><em>(<?php if(empty($album['dateExpires'])) { ?>Sharing token never expires<?php } else { ?>Sharing token expires on <?php $this->utility->dateLong($album['dateExpires']); ?><?php } ?>)</em></small>
</td>
<td>
<div class="pull-right">
<a href="<?php $this->url->albumView($album['data']); ?>"><i class="icon-eye-open icon-large"></i> View</a>
&nbsp; &nbsp; &nbsp;
<a href="/token/<?php $this->utility->safe($album['id']); ?>/delete" class="tokenDelete"><i class="icon-trash icon-large"></i> Delete</a>
</div>
</td>
</tr>
<?php } ?>
<?php } ?>
</table>
</div>
</div>

View File

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="${request.locale_name}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="pyramid web application">
<meta name="author" content="Pylons Project">
<link rel="shortcut icon" href="${request.static_url('soter:static/pyramid-16x16.png')}">
<title>Starter Scaffold for The Pyramid Web Framework</title>
<!-- Bootstrap core CSS -->
<link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this scaffold -->
<link href="${request.static_url('soter:static/theme.css')}" rel="stylesheet">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="starter-template">
<div class="container">
<div class="row">
<div class="col-md-2">
<img class="logo img-responsive" src="${request.static_url('soter:static/pyramid.png')}" alt="pyramid web framework">
</div>
<div class="col-md-10">
<div class="content">
<h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter scaffold</span></h1>
<p class="lead">Welcome to <span class="font-normal">${project}</span>, an&nbsp;application generated&nbsp;by<br>the <span class="font-normal">Pyramid Web Framework 1.5.7</span>.</p>
</div>
</div>
</div>
<div class="row">
<div class="links">
<ul>
<li class="current-version">Generated by v1.5.7</li>
<li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/">Docs</a></li>
<li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li>
<li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li>
<li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li>
</div>
</div>
<div class="row">
<div class="copyright">
Copyright &copy; Pylons Project
</div>
</div>
</div>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,37 @@
<div class="row">
<div class="span12">
<h2>Create an app</h2>
</div>
</div>
<div class="row">
<div class="span6">
<p>
<h3>Make sure you trust the site you just came from.</h3>
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.
</p>
</div>
</div>
<div class="row">
<div class="span12">
<form method="post">
<label for="name">A Name For Your App</label>
<input type="text" name="name" placeholder="Enter a name" value="<?php $this->utility->safe($name); ?>">
<!--<label>Permission</label>
<ul>
<li><input type="checkbox" name="permissions[]" value="read" class="checkbox" checked="true"> Read</li>
<li><input type="checkbox" name="permissions[]" value="create" class="checkbox"> Create</li>
<li><input type="checkbox" name="permissions[]" value="update" class="checkbox"> Update</li>
<li><input type="checkbox" name="permissions[]" value="delete" class="checkbox"> Delete</li>
</ul>-->
<div>
<button type="submit" class="btn btn-primary"><?php if($tokenType === 'access') { ?>Create and Approve<?php } else { ?>Create<?php } ?></button>
</div>
<input type="hidden" name="tokenType" value="<?php $this->utility->safe($tokenType); ?>">
<input type="hidden" name="oauth_callback" value="<?php $this->utility->safe($callback); ?>">
</form>
</div>
</div>

View File

@ -0,0 +1,68 @@
<form method="post" action="<?php $this->url->photoUpdate($photo['id']); ?>" id="photo-edit-form" class="photo-update-submit">
<input type="hidden" name="crumb" value="<?php $this->utility->safe($crumb); ?>">
<label for="title">Title</label>
<input type="text" name="title" id="title" placeholder="A title to describe your photo" value="<?php $this->utility->safe($photo['title']); ?>">
<label for="description">Description</label>
<textarea name="description" id="description" placeholder="A description of the photo (typically longer than the title)"><?php $this->utility->safe($photo['description']); ?></textarea>
<label for="tags">Tags</label>
<input type="text" name="tags" id="tags" class="typeahead-tags" placeholder="A comma separated list of tags" value="<?php $this->utility->safe(implode(',', $photo['tags'])); ?>">
<label for="latitude">Latitude &amp; Longitude</label>
<input type="text" class="input-small" name="latitude" id="latitude" placeholder="Lat, i.e. 49.73" value="<?php $this->utility->safe($photo['latitude']); ?>">
<input type="text" class="input-small" name="longitude" id="longtitude" placeholder="Lon, i.e. 18.34" value="<?php $this->utility->safe($photo['longitude']); ?>">
<div class="control-group">
<label class="control-label">Permission</label>
<div class="controls">
<label class="radio inline">
<input type="radio" name="permission" id="public" value="1" <?php if($photo['permission'] == 1) { ?> checked="checked" <?php } ?>>
Public
</label>
<label class="radio inline">
<input type="radio" name="permission" id="private" value="0" <?php if($photo['permission'] == 0) { ?> checked="checked" <?php } ?>>
Private
</label>
</div>
</div>
<?php if(count($albums) > 0) { ?>
<div class="control-group">
<label class="control-label">Albums</label>
<select class="typeahead" data-placeholder="Select albums for these photos" multiple name="albums[]" id="upload-albums">
<?php foreach($albums as $album) { ?>
<option value="<?php $this->utility->safe($album['id']); ?>" <?php if(isset($photo['albums']) && in_array($album['id'], $photo['albums'])) { ?> selected="selected" <?php } ?>>
<?php $this->utility->safe($album['name']); ?>
</option>
<?php } ?>
</select>
</div>
<?php } ?>
<?php if(count($groups) > 0) { ?>
<div class="control-group">
<label class="control-label">Groups</label>
<select class="typeahead" data-placeholder="Select groups for these photos" multiple name="groups[]" id="upload-groups">
<?php foreach($groups as $group) { ?>
<option value="<?php $this->utility->safe($group['id']); ?>" <?php if(isset($photo['groups']) && in_array($group['id'], $photo['groups'])) { ?> selected="selected" <?php } ?>>
<?php $this->utility->safe($group['name']); ?>
</option>
<?php } ?>
</select>
</div>
<?php } ?>
<label>License</label>
<div class="input">
<select name="license">
<?php foreach($licenses as $code => $license) { ?>
<option value="<?php $this->utility->safe($code); ?>"<?php if($license['selected']) { ?> selected="selected" <?php } ?>><?php $this->utility->licenseLong($code); ?></option>
<?php } ?>
</select>
</div>
<div>
<button class="btn btn-primary">Save</button>
</div>
</form>

View File

@ -0,0 +1,23 @@
<h4>Update your plugin: <em><?php $this->utility->safe($plugin); ?></em></h4>
<div class="row">
<div class="span12">
<form class="pluginUpdate" action="/plugin/<?php $this->utility->safe($plugin); ?>/update">
<table class="table left-header">
<?php foreach($conf as $k => $v) { ?>
<tr>
<td class="span2"><label><?php $this->utility->safe($k); ?></label></td>
<td><input type="text" name="<?php $this->utility->safe($k); ?>" value="<?php $this->utility->safe($v); ?>"></td>
</tr>
<?php } ?>
<tr>
<td></td>
<td>
<input type="hidden" name="crumb" value="<?php $this->utility->safe($crumb); ?>">
<button type="submit" class="btn btn-primary">Save</button>
</td>
</tr>
</table>
</form>
</div>
</div>
<a href="#" class="batchHide close" title="Close this dialog"><i class="icon-remove batchHide"></i></a>

View File

@ -0,0 +1,26 @@
<div id="setup">
<h1>Connect your Dropbox to Trovebox</h1>
<p>
<!--If you haven't already created a Dropbox app then <a href="https://www.dropbox.com/developers/apps" target="_blank">click here</a>.-->
<a href="https://www.dropbox.com/developers/apps" target="_blank">Click here</a> to create a Dropbox app if you haven't already.
<em>IMPORTANT:</em> make sure you select <em>App Folder</em> access level.
</p>
<div id="setup-dropbox">
<form action="/setup/dropbox<?php $this->utility->safe($qs); ?>" method="post" class="validate">
<h2>Enter your Dropbox App credentials</h2>
<label for="dropboxKey">Dropbox Key <em>(<a href="https://www.dropbox.com/developers/apps" target="_blank">found under options</a>)</em></label>
<input type="password" name="dropboxKey" id="dropboxKey" size="50" autocomplete="off" data-validation="required" placeholder="Dropbox consumer key or app key" value="<?php echo $dropboxKey; ?>">
<label for="dropboxSecret">Dropbox Secret</label>
<input type="password" name="dropboxSecret" id="dropboxSecret" size="50" autocomplete="off" data-validation="required" placeholder="Dropbox consumer secret or app secret" value="<?php echo $dropboxSecret; ?>">
<label for="dropboxFolder">Dropbox Folder Name <em>(a name for the folder we save photos to)</em></label>
<input type="text" name="dropboxFolder" id="dropboxFolder" size="50" autocomplete="off" data-validation="required alphanumeric" placeholder="An alpha numeric folder name" value="<?php echo $dropboxFolder; ?>">
<div class="btn-toolbar">
<?php if(isset($_GET['edit'])) { ?><a class="btn" href="/">Cancel</a><?php } ?>
<button type="submit" class="btn btn-primary">Continue to Dropbox</button>
</div>
</form>
</div>
</div>

135
soter/templates/setup.html Normal file
View File

@ -0,0 +1,135 @@
<div id="setup">
<h1>Create your Trovebox site <?php if(empty($qs)) { ?><em><a href="/setup/restart">(start over)</a></em><?php } ?></h1>
<ul class="nav nav-pills">
<?php for($i = 1; $i <= 3; $i++) { ?>
<li<?php echo ($step == $i) ? ' class="active"' : ''; ?>><a><?php echo $i; ?></a></li>
<?php } ?>
</ul>
<?php if(!empty($errors)) { ?>
<?php if(is_array($errors)) { ?>
<div class="alert alert-error">
<strong>Please fix the following errors</strong>
<ul class="errors">
<?php foreach($errors as $error) { ?>
<li><?php echo $error; ?></li>
<?php } ?>
</ul>
</div>
<?php } else { ?>
<p class="alert alert-error error">
<strong>Please fix the following errors</strong>
<?php echo $errors; ?>
</p>
<?php } ?>
<?php } ?>
<div id="setup-step-1"<?php echo ($step != 1) ? ' class="hidden"' : ''?>>
<form class="validate" action="/setup<?php echo $qs ?>" method="post">
<h2><?php if(isset($_GET['edit'])) { ?>Create Account<?php } else { ?>Account Settings<?php } ?></h2>
<label for="email">Email address</label>
<input type="text" name="email" id="email" placeholder="user@example.com" <?php if(isset($email)) { ?>value="<?php $this->utility->safe($email); ?>"<?php } ?> data-validation="required email">
<?php if($this->config->site->allowOpenPhotoLogin == 1) { ?>
<label for="email">Password</label>
<input type="password" name="password" id="password" placeholder="password" <?php if(isset($password)) { ?>value="<?php $this->utility->safe($password); ?>"<?php } ?> data-validation="required">
<?php } else { ?>
<input type="hidden" name="password" value="">
<?php } ?>
<input type="hidden" name="theme" value="fabrizio1.0">
<div class="btn-toolbar">
<?php if(isset($_GET['edit'])) { ?><a class="btn" href="/">Cancel</a><?php } ?>
<button class="btn btn-brand" type="submit">Continue to Step 2</button>
</div>
<input type="hidden" name="appId" id="appId" <?php if(isset($appId)) { ?>value="<?php $this->utility->safe($appId); ?>"<?php } ?>>
</form>
</div>
<div id="setup-step-2"<?php echo ($step != 2) ? ' class="hidden"' : ''?>>
<form action="/setup/2<?php echo $qs; ?>" method="post">
<h2>Site Settings <em>(the defaults work just fine<!--<a href="">what's this?</a>-->)</em></h2>
<label for="imageLibrary">Select Image Library (see <a href="https://github.com/photo/frontend/issues/662" target="_blank">#662</a> if using GD)</label>
<?php if(isset($imageLibs)) { ?>
<select name="imageLibrary" id="imageLibrary">
<?php foreach($imageLibs as $key => $val) { ?>
<option value="<?php echo $key; ?>"<?php echo ($imageLibrary == $key) ? ' selected="selected"' : '' ?>><?php echo $val; ?></option>
<?php } ?>
</select>
<?php } ?>
<input type="hidden" name="database" value="MySql">
<label for="fileSystem">Select File System</label>
<select name="fileSystem">
<option value="S3"<?php echo ($filesystem == 'S3') ? ' selected="selected"' : '' ?>>Amazon S3</option>
<option value="S3Dropbox"<?php echo ($filesystem == 'S3Dropbox') ? ' selected="selected"' : '' ?>>Amazon S3 + Dropbox</option>
<option value="Local"<?php echo ($filesystem == 'Local') ? ' selected="selected"' : '' ?>>Local filesystem</option>
<option value="LocalDropbox"<?php echo ($filesystem == 'LocalDropbox') ? ' selected="selected"' : '' ?>>Local filesystem + Dropbox</option>
<!--<option value="DreamObjects"<?php echo ($filesystem == 'DreamObjects') ? ' selected="selected"' : '' ?>>DreamObjects</option>-->
</select>
<div class="btn-toolbar">
<?php if(isset($_GET['edit'])) { ?><a class="btn" href="/">Cancel</a><?php } ?>
<button type="submit" class="btn btn-brand">Continue to Step 3</button>
</div>
</form>
</div>
<div id="setup-step-3"<?php echo ($step != 3) ? ' class="hidden"' : ''?>>
<form class="validate" action="/setup/3<?php echo $qs; ?>" method="post">
<h2>Credentials<!-- <em>(<a href="">what's this?</a>)</em>--></h2>
<?php if(isset($usesAws) && $usesAws) { ?>
<h3>Enter your Amazon credentials <em>(<a href="https://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key" target="_blank">what's this?</a>)</em></h3>
<label for="awsKey">Amazon Access Key ID</label>
<input type="password" name="awsKey" id="awsKey" placeholder="Your AWS access key" size="50" autocomplete="off" data-validation="required" value="<?php echo $awsKey; ?>">
<label for="awsSecret">Amazon Secret Access Key</label>
<input type="password" name="awsSecret" id="awsSecret" placeholder="Your AWS access secret" size="50" autocomplete="off" data-validation="required" value="<?php echo $awsSecret; ?>">
<label for="s3Bucket">Amazon S3 Bucket Name</label>
<?php if(isset($usesS3) && $usesS3) { ?>
<?php if(isset($s3Bucket) && !empty($s3Bucket)) { ?>
<input type="text" name="s3Bucket" id="s3Bucket" size="50" placeholder="Globally unique bucket name" value="<?php $this->utility->safe($s3Bucket); ?>" data-validation="required">
<?php } else { ?>
<input type="text" name="s3Bucket" id="s3Bucket" size="50" placeholder="Globally unique bucket name" value="<?php $this->utility->safe($_SERVER['HTTP_HOST']); ?>" data-validation="required">
<?php } ?>
<?php } ?>
<?php } ?>
<h3>Enter your MySQL credentials <!--<em>(<a href="">what's this?</a>)</em>--></h3>
<label for="mySqlHost">MySQL Host <em>(port is optional)</em></label>
<input type="text" name="mySqlHost" id="mySqlHost" placeholder="Your MySql host (i.e. 127.0.0.1:3306)" size="50" autocomplete="off" data-validation="required" value="<?php echo $mySqlHost; ?>">
<label for="mySqlUser">MySQL Username</label>
<input type="text" name="mySqlUser" id="mySqlUser" placeholder="Your MySql username" size="50" autocomplete="off" data-validation="required" value="<?php echo $mySqlUser; ?>">
<label for="mySqlPassword">MySQL Password</label>
<input type="password" name="mySqlPassword" id="mySqlPassword" placeholder="Your MySql password" size="50" autocomplete="off" value="<?php echo $mySqlPassword; ?>">
<label for="mySqlDb">MySQL Database <em>(make sure this database already exists)</em></label>
<input type="text" name="mySqlDb" placeholder="Name of your MySql database" id="mySqlDb" size="50" autocomplete="off" data-validation="required" value="<?php echo $mySqlDb; ?>">
<label for="mySqlTablePrefix">Table prefix <em>(optional)</em></label>
<input type="text" name="mySqlTablePrefix" placeholder="A prefix for all OpenPhoto tables" id="mySqlTablePrefix" size="50" autocomplete="off" value="<?php echo $mySqlTablePrefix; ?>">
<?php if((isset($usesLocalFs) && !empty($usesLocalFs))) { ?>
<h3>Enter your local file system credentials <!--<em>(<a href="">what's this?</a>)</em>--></h3>
<label for="fsRoot">File system root <em>(Must be writable by Apache user)</em></label>
<input type="text" name="fsRoot" id="fsRoot" size="50" placeholder="/home/username/openphoto/src/html/photos (full path to writable directory)" data-validation="required" value="<?php echo $fsRoot; ?>">
<label for="fsHost">File system hostname for download URL <em>(Web accessible w/o "http://")</em></label>
<input type="text" name="fsHost" id="fsHost" size="50" placeholder="example.com/photos (no http:// or trailing slash)" data-validation="required" value="<?php echo $fsHost; ?>">
<?php } ?>
<?php if(isset($usesDropbox) && !empty($usesDropbox)) { ?>
<input type="hidden" name="dropboxKey" value="<?php $this->utility->safe($dropboxKey); ?>">
<input type="hidden" name="dropboxSecret" value="<?php $this->utility->safe($dropboxSecret); ?>">
<input type="hidden" name="dropboxToken" value="<?php $this->utility->safe($dropboxToken); ?>">
<input type="hidden" name="dropboxTokenSecret" value="<?php $this->utility->safe($dropboxTokenSecret); ?>">
<input type="hidden" name="dropboxFolder" value="<?php $this->utility->safe($dropboxFolder); ?>">
<?php } ?>
<div class="btn-toolbar">
<?php if(isset($_GET['edit'])) { ?><a class="btn" href="/">Cancel</a><?php } ?>
<button type="submit" class="btn btn-brand">Complete setup</button>
</div>
</form>
</div>
</div>

View File

@ -0,0 +1,30 @@
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title><?php getTheme()->meta('titles', $page); ?></title>
<meta name="description" content="<?php getTheme()->meta('descriptions', $page); ?>">
<meta name="keywords" content="<?php getTheme()->meta('keywords', $page); ?>">
<meta name="author" content="">
<meta name="viewport" content="width=device-width; initial-scale = 1.0; maximum-scale=1.0;" />
<link rel="shortcut icon" href="<?php getTheme()->asset('image', 'favicon.ico'); ?>">
<link rel="apple-touch-icon" href="<?php getTheme()->asset('image', 'apple-touch-icon.png'); ?>">
<link rel="stylesheet" href="/assets/stylesheets/html5_boilerplate_style.css">
<link rel="stylesheet" href="/assets/stylesheets/basics.css">
<link rel="stylesheet" href="/assets/stylesheets/main.css" media="screen and (min-device-width: 481px)">
<link rel="stylesheet" href="/assets/stylesheets/mobile.css" media="screen and (max-device-width: 480px)">
</head>
<body class="<?php echo $page; ?>">
<header>
<h1><div class="offscreen">Trovebox</div></h1>
</header>
<div class="container">
<?php echo $body; ?>
</div>
</body>
</html>

View File

@ -0,0 +1,20 @@
<h1>We need to upgrade from <?php $this->utility->safe($lastVersion); ?> to <?php $this->utility->safe($currentVersion); ?></h1>
<p>
Before you start the upgrade you'll want to make sure you have a backup of your database.
</p>
<?php if(!empty($readmes)) { ?>
<?php foreach($readmes as $version => $readme) { ?>
<h2>Notes for upgrading to <?php $this->utility->safe($version); ?></h2>
<p>
<?php echo $readme; // allow for html here?>
<p>
<?php } ?>
<?php } ?>
<p>
<form action="/upgrade" method="post">
<button type="submit" class="btn btn-primary">Begin upgrade</button>
</form>
</p>

View File

@ -0,0 +1,59 @@
<form class="upload dropzone form-stacked" method="post" action="/photo/upload">
<div class="row">
<div class="span3">
<h3>Details for your photos</h3>
<label for="title">Title</label>
<input type="search" name="title" placeholder="A title for these photos">
<label for="tags">Tags</label>
<input type="search" name="tags" class="typeahead tags" autocomplete="off" placeholder="Optional comma separated list">
<div class="control-group">
<label class="control-label">Albums <small>(<a href="#" class="showBatchForm album" data-action="albums">create new</a>)</small></label>
<select data-placeholder="Select albums for these photos" name="albums" class="typeahead">
<option value="">If you'd like, choose an album</option>
<?php foreach($albums as $album) { ?>
<option value="<?php $this->utility->safe($album['id']); ?>"><?php $this->utility->safe($album['name']); ?></option>
<?php } ?>
</select>
</div>
<div class="control-group">
<label for="tags">Permission</label>
<div class="controls">
<label class="radio inline private">
<input type="radio" name="permission" value="0"<?php if($preferences['permission'] === false || $preferences['permission'] === '0') { ?> checked="checked"<?php } ?>>
<span>Private</span>
</label>
<label class="radio inline">
<input type="radio" name="permission" value="1"<?php if($preferences['permission'] === '1') { ?> checked="checked"<?php } ?>>
<span>Public</span>
</label>
</div>
</div>
<label for="license">License</label>
<select name="license" class="license">
<?php foreach($licenses as $code => $license) { ?>
<option value="<?php $this->utility->safe($code); ?>" <?php if($license['selected']) { ?> selected="selected" <?php } ?>><?php $this->utility->licenseName($code); ?></option>
<?php } ?>
</select>
<input type="hidden" name="crumb" value="<?php $this->utility->safe($crumb); ?>">
<input type="hidden" name="httpCodes" value="500,200,403,401">
<input type="hidden" name="returnSizes" value="100x100xCR">
<div class="btn-toolbar">
<button type="button" class="btn btn-brand uploadBeta">Start uploading</button>
</div>
<div class="progress-upload progress-meta"></div>
<small><em>Powered by <a href="http://www.dropzonejs.com/" target="_blank">Dropzone.js</a></em></small>
</div>
<div class="span9">
<div class="bucket">
<div class="default message"></div>
<div class="preview-container"></div>
</div>
</div>
</div>
</form>

View File

@ -0,0 +1,59 @@
<?php if(count($successPhotos) > 0) { ?>
<?php if(count($failure) === 0) { ?>
<h2>Your photos are finished uploading! Now what?</h2>
<?php } else { ?>
<h2>Your photos are finished uploading, but <?php echo count($failure); ?> had problems. Now what?</h2>
<?php } ?>
<p>
Post your photos to <?php if($facebookId) { ?>Facebook or <?php } ?>Twitter.
<ul class="unstyled upload-share">
<li>
<a href="https://twitter.com/intent/tweet?original_referer=<?php $this->utility->getAbsoluteUrl(''); ?>&text=<?php echo urlencode('I just uploaded some photos on @OpenPhoto.'); ?>&url=<?php echo urlencode($this->utility->getAbsoluteUrl($url, false)); ?>" class="btn btn-theme-secondary sharePopup" data-width="575" data-height="400"><i class="icon-twitter icon-large"></i> Share on Twitter</a>
</li>
<?php if($facebookId) { ?>
<li>
<a href="https://www.facebook.com/dialog/feed?app_id=<?php $this->utility->safe($facebookId); ?>&link=<?php $this->utility->getAbsoluteUrl($url); ?>&picture=<?php $this->utility->safe($successPhotos[0][$this->config->photoSizes->thumbnail]); ?>&name=My+photos+on+OpenPhoto&description=I+uploaded+some+photos+on+OpenPhoto.&display=popup" class="btn btn-theme-secondary share-facebook-click"
data-link="<?php $this->utility->getAbsoluteUrl($url); ?>" data-picture="<?php $this->utility->safe($successPhotos[0][$this->config->photoSizes->thumbnail]); ?>" data-name="My photos on OpenPhoto" data-description="I uploaded some photos on OpenPhoto." data-display=popup" data-width="450" data-height="300"><i class="icon-facebook icon-large"></i> Share on Facebook</a>
</li>
<?php } ?>
</ul>
</p>
<p>
Or simply go <a href="<?php $this->url->photosView(sprintf('ids-%s', $successIds)); ?>">look at your photos</a>.
</p>
<?php } else { // no photos uploaded ?>
<h2>None of your photos were uploaded</h2>
<p>
See below for more details. If you continue to have problems drop us a note on our mailing list <a href="mailto:support@trovebox.com">support@trovebox.com</a>.
</p>
<?php } ?>
<?php if(count($successPhotos) > 0) { ?>
<h3>Here's a breakdown of your upload</h3>
<strong><span class="label label-success"><?php printf('%d %s %s', count($successPhotos), $this->utility->plural(count($successPhotos), 'photo', false), $this->utility->selectPlural(count($successPhotos), 'was', 'were', false)); ?> uploaded successfully.</span></strong>
<div class="upload-preview success photo-grid">
<div class="photo-grid-hr"></div>
</div>
<hr>
<?php } ?>
<?php if(count($duplicatePhotos) > 0) { ?>
<strong><span class="label label-warning"><?php echo count($duplicatePhotos); ?> of them already existed in your account.</span></strong>
<div class="upload-preview">
<ul class="thumbnails duplicates">
<?php foreach($duplicatePhotos as $photo) { ?>
<li><a href="<?php $this->utility->safe($photo['url']); ?>" class="thumbnail"><img src="<?php $this->utility->safe($photo[$this->config->photoSizes->thumbnail]); ?>"></a></li>
<?php } ?>
</ul>
</div>
<hr>
<?php } ?>
<?php if(count($failure) > 0) { ?>
<strong><span class="label label-important"><?php printf('%d %s', count($failure), $this->utility->plural(count($failure), 'photo', false)); ?> could not be uploaded. Booo!</span></strong>
<div>
<ul>
<?php foreach($failure as $name) { ?>
<li><?php $this->utility->safe($name); ?></li>
<?php } ?>
</ul>
</div>
<?php } ?>

View File

@ -0,0 +1,10 @@
<h2>Enter your name or nickname</h2>
<form class="form-stacked uploadTokenDialog">
<div class="control-group">
<input type="text" name="identifier" placeholder="your name or nickname" class="input-large fixed">
<div><small><i class="icon-info-sign"></i> This helps the account owner know these are your photos</small></div>
</div>
<div class="btn-toolbar">
<button class="btn btn-brand wide">Continue</button>
</div>
</form>

View File

@ -0,0 +1,76 @@
<div class="hide row upload-confirm"></div>
<div class="upload-container">
<div class="upload-message upload-progress"><img src="/assets/images/upload-big.gif" align="absmiddle">Currently uploading <span class="completed">0</span> of <span class="total">0</span> photos.</div>
<form class="upload form-stacked photo-upload-submit" method="post" action="/photo/upload">
<div class="row">
<br>
<div class="span8">
<h3>Upload from your computer</h3>
<div id="uploader">
<div class="insufficient">
<h1>Unfortunately, it doesn't look like we support your browser. :(</h1>
<p>
Try using <a href="http://www.mozilla.org/en-US/firefox/new/">Firefox</a>.
</p>
</div>
</div>
<?php if(!empty($token)) { ?>
<div class="btn-toolbar visible-phone">
<button type="submit" class="btn btn-brand upload-button addSpinner wide">Start uploading</button>
</div>
<?php } ?>
<em class="poweredby hidden-phone">Powered by <a href="http://www.plupload.com">Plupload</a>.</em>
</div>
<div class="span4 <?php if(!empty($token)) { ?>hide<?php } ?>">
<h3>Use these settings.</h3>
<br>
<label for="tags">Tags</label>
<input type="search" name="tags" class="typeahead tags" autocomplete="off" placeholder="Optional comma separated list">
<div class="control-group">
<label class="control-label">Albums <small>(<a href="#" class="showBatchForm album" data-action="albums">create new</a>)</small></label>
<select data-placeholder="Select albums for these photos" name="albums" class="typeahead">
<option value="">If you'd like, choose an album</option>
<?php foreach($albums as $album) { ?>
<option value="<?php $this->utility->safe($album['id']); ?>"><?php $this->utility->safe($album['name']); ?></option>
<?php } ?>
</select>
</div>
<div class="control-group">
<label for="tags">Permission</label>
<div class="controls">
<label class="radio inline private">
<input type="radio" name="permission" value="0"<?php if($preferences['permission'] === false || $preferences['permission'] === '0') { ?> checked="checked"<?php } ?>>
<span>Private</span>
</label>
<label class="radio inline">
<input type="radio" name="permission" value="1"<?php if($preferences['permission'] === '1') { ?> checked="checked"<?php } ?>>
<span>Public</span>
</label>
</div>
</div>
<?php if(empty($token)) { ?>
<label for="license">License</label>
<select name="license" class="license">
<?php foreach($licenses as $code => $license) { ?>
<option value="<?php $this->utility->safe($code); ?>" <?php if($license['selected']) { ?> selected="selected" <?php } ?>><?php $this->utility->licenseName($code); ?></option>
<?php } ?>
</select>
<?php } else { ?>
<input type="hidden" name="license" value="<?php reset($licenses); $this->utility->safe(key($licenses)); ?>">
<?php } ?>
<input type="hidden" name="crumb" value="<?php $this->utility->safe($crumb); ?>">
<?php if(empty($token)) { ?>
<div class="btn-toolbar visible-phone">
<button type="submit" class="btn btn-brand upload-button addSpinner wide">Start uploading</button>
</div>
<?php } ?>
</div>
</div>
</form>
</div>

17
soter/tests.py Normal file
View File

@ -0,0 +1,17 @@
import unittest
from pyramid import testing
class ViewTests(unittest.TestCase):
def setUp(self):
self.config = testing.setUp()
def tearDown(self):
testing.tearDown()
def test_my_view(self):
from .views import my_view
request = testing.DummyRequest()
info = my_view(request)
self.assertEqual(info['project'], 'Soter')

6
soter/views.py Normal file
View File

@ -0,0 +1,6 @@
from pyramid.view import view_config
@view_config(route_name='home', renderer='templates/mytemplate.pt')
def my_view(request):
return {'project': 'Soter'}