Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
Choose a Base Repository
hypothesis/h
40a/h
AFDudley/h
BigBlueHat/h
BinaryStars/h
CCH543/h
Cinemacloud/h
Ericgood/h
FTG-003/h
Forethinker/h
GratefulTony/h
HGldJ1966/h
JJediny/h
John-Williams/h
Laurian/h
LittleFancy/h
MattyQ/h
Mishkin2015/h
RichardLitt/h
Staffan1/h
SteelWagstaff/h
TowerBR/h
VanyTang/h
abigailricarte/h
ackermann/h
alecchap/h
alesarrett/h
alexsegura/h
almereyda/h
alon/h
andzi/h
angelicxsoul/h
ansmoh/h
apurvajalit/h
arjunvasan/h
asdevor/h
bZichett/h
badgettrg/Webmarks
balmas/h
balupton/h
bbarker/h
bennlich/h
benthor/h
blakewest/h
bogste/h
bradparks/h
brittanystoroz/h
buiquangchien/h
cdchapman/h
charblanc/h
chowsamihq/h
chr7stos/Webmarks
chrber/h
chrismPssina/h
christinaphamAD/h
cmbirk/h
codeaudit/h
coolcool21/h
cove/h
csillag/h
danjimilk/h
dannyhope/h
daredream/h
davidmcclure/h
dennisplucinik/h
dezynetechnologies/h
diegodlh/h
djcun95/h
donsequitur/h
edsu/h
eiro10/h
emckean/h
ercchy/h
eshellman/h
fangang123/h
fchasen/h
fcrimins/h
fhirsch/h
ficolo/h
fragkopoulos/h
gauravkeerthi/h
geass/h
gergely-ujvari/h
gitter-badger/h
gnott/h
gobengo/h
gorinovic/h
gus3000/h
hashin/h
helemaalbigt/h
hmstepanek/h
hwasiti/h
hylhero/h
hyperstudio/h
iHDeveloper/h
imeysam/h
jackspaceBerkeley/h
jarey/h
jasdeep/h
jason790/h
jasonzou/j
jazahn/h
jccr/h
jean/h
jeka57/h
jeremydean/h
jermnelson/h
jibe-b/h
jnishiyama/h
jojksd/h
jpadilla/h
jtremback/h
judell/h
juli-so/h
kabacs/h
karissa/h
kaushikvijay/h
kaydoh/h
kill4uk/h
klopiinas/h
klrkdekira/h
koulihong311/h
krassif/h
krstnkngs/h
leoqmp/h
linhua55/h
lucadealfaro/h
lyspooner/h
lyzadanger/h
m1yag1/h
magee/h
mambocab/h
manunymous/h
maraino/h
mari-ja/h
markbarratt/h
martinq/h
mbbaig/h
mcarv63/h
meawoppl/h
meflyup/h
metasj/h
mgasner/h
mgax/h
mollycr/h
mrchrisadams/h
mrienstra/h
mshavlovsky/h
muddasani/h
nagyist/hyphothesis-h
nagyistoce/hypothesis-h
nanxio/h
neozhangthe1/h
ningyifan/h
nkingsley/h
nlholdem/h
nlisgo/h
noscripter/h
nshkuro/h
odnodn/h
oliversauter/h
openbizgit/h
opengovfoundation/h
openstax/hypothesis-server
ouroboros8/h
pablomarti/h
pamo/h
philipn/h
philschatz/h
pinballwonder/h
plainspace/h
raowl/h
rickyhan/h
rmoorman/h
rmtsukuru/h
robertknight/h
rowhit/h
rsarxiv/h
saakaifoundry/h
samrose/h
scharf/h
shepazu/h
sherah/h
shofheinz/h
soapdog/h
ssin122/test-h
st-fresh/h
stuk88/h
sylvanmist/h
tetratorus/h
tilgovi/h
tomnar/h
trivenews/h
truthadjustr/h
utngz/h
voidfiles/h
wenchen/h
yargevad/h
yumatch/h
zshen777/h
Nothing to show
Choose a Head Repository
hypothesis/h
40a/h
AFDudley/h
BigBlueHat/h
BinaryStars/h
CCH543/h
Cinemacloud/h
Ericgood/h
FTG-003/h
Forethinker/h
GratefulTony/h
HGldJ1966/h
JJediny/h
John-Williams/h
Laurian/h
LittleFancy/h
MattyQ/h
Mishkin2015/h
RichardLitt/h
Staffan1/h
SteelWagstaff/h
TowerBR/h
VanyTang/h
abigailricarte/h
ackermann/h
alecchap/h
alesarrett/h
alexsegura/h
almereyda/h
alon/h
andzi/h
angelicxsoul/h
ansmoh/h
apurvajalit/h
arjunvasan/h
asdevor/h
bZichett/h
badgettrg/Webmarks
balmas/h
balupton/h
bbarker/h
bennlich/h
benthor/h
blakewest/h
bogste/h
bradparks/h
brittanystoroz/h
buiquangchien/h
cdchapman/h
charblanc/h
chowsamihq/h
chr7stos/Webmarks
chrber/h
chrismPssina/h
christinaphamAD/h
cmbirk/h
codeaudit/h
coolcool21/h
cove/h
csillag/h
danjimilk/h
dannyhope/h
daredream/h
davidmcclure/h
dennisplucinik/h
dezynetechnologies/h
diegodlh/h
djcun95/h
donsequitur/h
edsu/h
eiro10/h
emckean/h
ercchy/h
eshellman/h
fangang123/h
fchasen/h
fcrimins/h
fhirsch/h
ficolo/h
fragkopoulos/h
gauravkeerthi/h
geass/h
gergely-ujvari/h
gitter-badger/h
gnott/h
gobengo/h
gorinovic/h
gus3000/h
hashin/h
helemaalbigt/h
hmstepanek/h
hwasiti/h
hylhero/h
hyperstudio/h
iHDeveloper/h
imeysam/h
jackspaceBerkeley/h
jarey/h
jasdeep/h
jason790/h
jasonzou/j
jazahn/h
jccr/h
jean/h
jeka57/h
jeremydean/h
jermnelson/h
jibe-b/h
jnishiyama/h
jojksd/h
jpadilla/h
jtremback/h
judell/h
juli-so/h
kabacs/h
karissa/h
kaushikvijay/h
kaydoh/h
kill4uk/h
klopiinas/h
klrkdekira/h
koulihong311/h
krassif/h
krstnkngs/h
leoqmp/h
linhua55/h
lucadealfaro/h
lyspooner/h
lyzadanger/h
m1yag1/h
magee/h
mambocab/h
manunymous/h
maraino/h
mari-ja/h
markbarratt/h
martinq/h
mbbaig/h
mcarv63/h
meawoppl/h
meflyup/h
metasj/h
mgasner/h
mgax/h
mollycr/h
mrchrisadams/h
mrienstra/h
mshavlovsky/h
muddasani/h
nagyist/hyphothesis-h
nagyistoce/hypothesis-h
nanxio/h
neozhangthe1/h
ningyifan/h
nkingsley/h
nlholdem/h
nlisgo/h
noscripter/h
nshkuro/h
odnodn/h
oliversauter/h
openbizgit/h
opengovfoundation/h
openstax/hypothesis-server
ouroboros8/h
pablomarti/h
pamo/h
philipn/h
philschatz/h
pinballwonder/h
plainspace/h
raowl/h
rickyhan/h
rmoorman/h
rmtsukuru/h
robertknight/h
rowhit/h
rsarxiv/h
saakaifoundry/h
samrose/h
scharf/h
shepazu/h
sherah/h
shofheinz/h
soapdog/h
ssin122/test-h
st-fresh/h
stuk88/h
sylvanmist/h
tetratorus/h
tilgovi/h
tomnar/h
trivenews/h
truthadjustr/h
utngz/h
voidfiles/h
wenchen/h
yargevad/h
yumatch/h
zshen777/h
Nothing to show
  • 8 commits
  • 22 files changed
  • 0 commit comments
  • 3 contributors
Commits on Feb 26, 2015
Commits on Mar 02, 2015
Merge pull request #1971 from hypothesis/fix-og-title
Fix og:title output; Handle list or string value
Commits on Mar 04, 2015
Make it possible to instantiate the API from paste
At the moment it's not easy to get a shell with `h.auth` configured,
because only the API application includes `h.auth` and there is no easy
way to get a pshell[1] for the API.

This commit adds a setuptools `paste.app_factory` entrypoint for the API
application, making it possible to run

    pshell development.ini#api

to get a shell configured for the API.

[1]: http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/commandline.html
Convert h.api module into a package
This is a refactoring of the h.api module into a package.

- the get_user helper moves to h.api.auth
- elasticsearch setup moves to h.api.db
- views move to h.api.views
Don't include streamer or notification in API app
Eventually it's possible that the streamer should become part of the
API, but the notification package should probably not, and was only
added (in b8c7863) as a temporary measure.

Remove them both for now, in the spirit of making sure that code
executes either in the main application, or in the API application, but
not both: integration between the main app and the API should eventually
be through the API or through external persistent message queues only.
View
@@ -2,6 +2,12 @@
pipeline: h
[app:api]
use: egg:h#api
basemodel.should_create_all: True
[app:h]
use: egg:h
View
@@ -1,19 +1,4 @@
# -*- coding: utf-8 -*-
"""Initialize configuration."""
from .app import main
from ._version import get_versions
__version__ = get_versions()['version']
del get_versions
__all__ = ['main']
def includeme(config):
"""Include config sections and setup Jinja."""
config.include('.views')
config.include('pyramid_jinja2')
config.add_jinja2_renderer('.js')
config.add_jinja2_renderer('.txt')
config.add_jinja2_renderer('.html')
View
No changes.
View
@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
from annotator.auth import Consumer, User
def get_user(request):
"""Create a User object for annotator-store."""
userid = request.unauthenticated_userid
if userid is not None:
for principal in request.effective_principals:
if principal.startswith('consumer:'):
key = principal[9:]
consumer = Consumer(key)
return User(userid, consumer, False)
return None
View
@@ -0,0 +1,141 @@
# -*- coding: utf-8 -*-
import logging
import time
from annotator import es
from elasticsearch import exceptions as elasticsearch_exceptions
from pyramid.settings import asbool
from .models import Annotation
from .models import Document
log = logging.getLogger(__name__)
def store_from_settings(settings):
"""Configure the Elasticsearch wrapper provided by annotator-store."""
if 'es.host' in settings:
es.host = settings['es.host']
if 'es.index' in settings:
es.index = settings['es.index']
if 'es.compatibility' in settings:
es.compatibility_mode = settings['es.compatibility']
# We want search results to be filtered according to their
# read-permissions, which is done in the store itself.
es.authorization_enabled = True
return es
def _ensure_es_plugins(es_conn):
"""Ensure that the ICU analysis plugin is installed for ES."""
# Pylint issue #258: https://bitbucket.org/logilab/pylint/issue/258
#
# pylint: disable=unexpected-keyword-arg
names = [x.strip() for x in es_conn.cat.plugins(h='component').split('\n')]
if 'analysis-icu' not in names:
message = ("ICU Analysis plugin is not installed for ElasticSearch\n"
" See the installation instructions for more details:\n"
" https://github.com/hypothesis/h/blob/master/"
"INSTALL.rst#installing")
raise RuntimeError(message)
def create_db():
"""Create the ElasticSearch index for Annotations and Documents."""
# Check for required plugin(s)
_ensure_es_plugins(es.conn)
models = [Annotation, Document]
mappings = {}
analysis = {}
# Collect the mappings and analysis settings
for model in models:
mappings.update(model.get_mapping())
for section, items in model.get_analysis().items():
existing_items = analysis.setdefault(section, {})
for name in items:
if name in existing_items:
fmt = "Duplicate definition of 'index.analysis.{}.{}'."
msg = fmt.format(section, name)
raise RuntimeError(msg)
existing_items.update(items)
# Create the index
try:
# Pylint issue #258: https://bitbucket.org/logilab/pylint/issue/258
#
# pylint: disable=unexpected-keyword-arg
response = es.conn.indices.create(es.index, ignore=400, body={
'mappings': mappings,
'settings': {'analysis': analysis},
})
except elasticsearch_exceptions.ConnectionError as e:
msg = ('Can not access ElasticSearch at {0}! '
'Check to ensure it is running.').format(es.host)
raise elasticsearch_exceptions.ConnectionError('N/A', msg, e)
# Bad request (400) is ignored above, to prevent warnings in the log, but
# the failure could be for reasons other than that the index exists. If so,
# raise the error here.
if 'error' in response and 'IndexAlreadyExists' not in response['error']:
raise elasticsearch_exceptions.RequestError(400, response['error'])
# Update analysis settings
settings = es.conn.indices.get_settings(index=es.index)
existing = settings[es.index]['settings']['index'].get('analysis', {})
if existing != analysis:
try:
es.conn.indices.close(index=es.index)
es.conn.indices.put_settings(index=es.index, body={
'analysis': analysis
})
finally:
es.conn.indices.open(index=es.index)
# Update mappings
try:
for doc_type, body in mappings.items():
es.conn.indices.put_mapping(
index=es.index,
doc_type=doc_type,
body=body
)
except elasticsearch_exceptions.RequestError as e:
if e.error.startswith('MergeMappingException'):
date = time.strftime('%Y-%m-%d')
message = ("Elasticsearch index mapping is incorrect! Please "
"reindex it. For example, run: "
"./bin/hypothesis reindex {0} {1} {1}-{2}"
.format('yourconfig.ini', es.index, date)
)
log.critical(message)
raise RuntimeError(message)
raise
def delete_db():
"""Delete the Annotation and Document databases."""
Annotation.drop_all()
Document.drop_all()
def includeme(config):
"""Configure and possibly initialize ElasticSearch and its models."""
registry = config.registry
settings = registry.settings
# Configure ElasticSearch
store_from_settings(settings)
# Maybe initialize the models
if asbool(settings.get('basemodel.should_drop_all', False)):
delete_db()
if asbool(settings.get('basemodel.should_create_all', False)):
create_db()
View
@@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
from ..models import Annotation
from ..models import Document
__all__ = [
'Annotation',
'Document'
]
View
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
from pyramid.security import Allow, Authenticated, ALL_PERMISSIONS
from .models import Annotation
class Resource(dict):
"""
Resource is an entry in the traversal tree.
"""
__name__ = None
__parent__ = None
def __init__(self, request):
pass
def add(self, name, obj):
obj.__name__ = name
obj.__parent__ = self
self[name] = obj
class Annotations(object):
"""
Annotations is a container resource that exposes annotations as its
children in the tree.
"""
def __getitem__(self, key):
instance = Annotation.fetch(key)
if instance is None:
raise KeyError(key)
instance.__name__ = key
instance.__parent__ = self
return instance
class Root(Resource):
__acl__ = [
(Allow, 'group:admin', ALL_PERMISSIONS),
(Allow, Authenticated, 'create'),
]
def __init__(self, request):
self.add('annotations', Annotations())
View
@@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
def set_user_from_oauth(event):
"""A subscriber that checks requests for OAuth credentials and sets the
'REMOTE_USER' environment key to the authorized user (or ``None``)."""
request = event.request
request.verify_request()
request.environ['REMOTE_USER'] = getattr(request, 'user', None)
View
No changes.
Oops, something went wrong.

No commit comments for this range