# Path: suma/core/services/link.py
# class LinkService(object):
# 
#     def __init__(self, dbsession, hashid):
#         self.dbsession = dbsession
#         self.hashid = hashid
# 
#     def create_link(self, url, user_id=None):
#         created = False
#         link = self.get_link_by_url(url, user_id)
#         if link:
#             return link, created
# 
#         nextid = self.dbsession.execute(Sequence("link_id_seq"))
#         hashid = self.hashid.encode(nextid)
#         link = Link(
#             id=nextid,
#             user_id=user_id,
#             url=url,
#             hashid=hashid
#         )
#         self.dbsession.begin_nested()
#         try:
#             self.dbsession.add(link)
#             self.dbsession.commit()
#             created = True
#         except IntegrityError:
#             self.dbsession.rollback()
#             link = self.get_link_by_url(url, user_id)
# 
#         return link, created
# 
#     def get_link_by_id_or_hashid(self, id_or_hashid):
#         args = []
#         if str(id_or_hashid).isdigit():
#             args.append(Link.id == id_or_hashid)
#         args.append(Link.hashid == str(id_or_hashid))
#         try:
#             return self.dbsession.query(Link).filter(
#                 or_(*args)
#             ).one()
#         except NoResultFound:
#             return None
# 
#     def get_link_by_url(self, url, user_id=None):
#         l_query = self.dbsession.query(Link)
#         return l_query.filter(Link.url == url, Link.user_id == user_id).first()
# 
#     def get_link_by_id(self, id):
#         return self.dbsession.query(Link).filter(Link.id == id).first()
# 
#     def get_link_by_hashid(self, hashid):
#         return self.dbsession.query(Link).filter(Link.hashid == hashid).first()
# 
#     def ban_url(self, url, mode='url'):
#         assert mode in ('url', 'netloc', 'path'),\
#             'Bad mode is not "url", "netloc" or "path"'
#         hash_url, hash_netloc, hash_path = create_url_hashes(url)
#         hdict = dict(zip(('url', 'netloc', 'path'), (hash_url, hash_netloc, hash_path)))
#         btype = BlockingType.from_string(mode)
#         bl = BlockedLink(
#             hash=hdict[mode],
#             url=url,
#             type=btype
#         )
#         self.dbsession.begin_nested()
#         try:
#             self.dbsession.add(bl)
#             self.dbsession.commit()
#         except IntegrityError:
#             # already blocked so we me ignore
#             self.dbsession.rollback()
# 
# Path: suma/core/services/hashid.py
# class HashIdService(object):
#     def __init__(self, secret):
#         self.hashids = hashids.Hashids(secret, min_length=6)
# 
#     def encode(self, primary_id, secondary_id=None):
#         args = []
#         if secondary_id is not None:
#             # Using the primary_id as 1st argument create better entropy
#             # The same user with different link will get very different ids
#             args.append(secondary_id)
#         args.append(primary_id)
#         return self.hashids.encode(*args)
# 
#     def decode(self, short_id):
#         # we are reversing the order to respect primary first in the return
#         return self.hashids.decode(short_id)[::-1] # we use the step to ensure a tuple
# 
# Path: suma/core/services/file.py
# class LocalFileService(object):
#     def __init__(self, base_url, base_path):
#         suffix = ''
#         if not base_url.endswith('/'):
#             suffix = '/'
#         self.storage = LocalFileStorage(base_path, base_url + suffix)
# 
#     def create(self, data, filename, folder):
#         output = StringIO(data)
#         return self.storage.save_file(output, filename, folder)  # return final filename
# 
#     def url(self, filename):
#         return self.storage.url(filename)
# 
# class S3FileService(LocalFileService):
#     def __init__(self, base_url, bucket_name, access_key, secret_key):
#         suffix = ''
#         if not base_url.endswith('/'):
#             suffix = '/'
#         self.storage = S3FileStorage(
#             bucket_name=bucket_name,
#             base_url=base_url + suffix,
#             access_key=access_key,
#             secret_key=secret_key
#         )
# 
# Path: suma/core/services/task.py
# class TaskService(object):
#     def add_click(self, link_id, ip=None, referer=None):
#         assert type(link_id) in [IntType, LongType], "link_id is not an integer: %r" % link_id
#         tasks.add_click_task.apply_async((link_id, ip, referer), serializer='json')
# 
#     def get_link_data(self, link_id):
#         assert type(link_id) in [IntType, LongType], "link_id is not an integer: %r" % link_id
#         tasks.get_link_data_task.apply_async((link_id, ), serializer='json')


from suma.core.services import (
    LinkService,
    HashIdService,
    TaskService,
    S3FileService,
    LocalFileService
)
from paste.deploy.converters import asbool


def link_service_factory(context, request):
    dbsession = request.find_service(name='db', context=context)
    hashid = request.find_service(name='hashid', context=context)
    return LinkService(
        dbsession=dbsession,
        hashid=hashid,
    )


def hashid_service_factory(context, request):
    hashid_secret = request.registry.settings.get('hashid.secret')
    return HashIdService(
        secret=hashid_secret
    )



# Path: suma/core/services/link.py
# class LinkService(object):
# 
#     def __init__(self, dbsession, hashid):
#         self.dbsession = dbsession
#         self.hashid = hashid
# 
#     def create_link(self, url, user_id=None):
#         created = False
#         link = self.get_link_by_url(url, user_id)
#         if link:
#             return link, created
# 
#         nextid = self.dbsession.execute(Sequence("link_id_seq"))
#         hashid = self.hashid.encode(nextid)
#         link = Link(
#             id=nextid,
#             user_id=user_id,
#             url=url,
#             hashid=hashid
#         )
#         self.dbsession.begin_nested()
#         try:
#             self.dbsession.add(link)
#             self.dbsession.commit()
#             created = True
#         except IntegrityError:
#             self.dbsession.rollback()
#             link = self.get_link_by_url(url, user_id)
# 
#         return link, created
# 
#     def get_link_by_id_or_hashid(self, id_or_hashid):
#         args = []
#         if str(id_or_hashid).isdigit():
#             args.append(Link.id == id_or_hashid)
#         args.append(Link.hashid == str(id_or_hashid))
#         try:
#             return self.dbsession.query(Link).filter(
#                 or_(*args)
#             ).one()
#         except NoResultFound:
#             return None
# 
#     def get_link_by_url(self, url, user_id=None):
#         l_query = self.dbsession.query(Link)
#         return l_query.filter(Link.url == url, Link.user_id == user_id).first()
# 
#     def get_link_by_id(self, id):
#         return self.dbsession.query(Link).filter(Link.id == id).first()
# 
#     def get_link_by_hashid(self, hashid):
#         return self.dbsession.query(Link).filter(Link.hashid == hashid).first()
# 
#     def ban_url(self, url, mode='url'):
#         assert mode in ('url', 'netloc', 'path'),\
#             'Bad mode is not "url", "netloc" or "path"'
#         hash_url, hash_netloc, hash_path = create_url_hashes(url)
#         hdict = dict(zip(('url', 'netloc', 'path'), (hash_url, hash_netloc, hash_path)))
#         btype = BlockingType.from_string(mode)
#         bl = BlockedLink(
#             hash=hdict[mode],
#             url=url,
#             type=btype
#         )
#         self.dbsession.begin_nested()
#         try:
#             self.dbsession.add(bl)
#             self.dbsession.commit()
#         except IntegrityError:
#             # already blocked so we me ignore
#             self.dbsession.rollback()
# 
# Path: suma/core/services/hashid.py
# class HashIdService(object):
#     def __init__(self, secret):
#         self.hashids = hashids.Hashids(secret, min_length=6)
# 
#     def encode(self, primary_id, secondary_id=None):
#         args = []
#         if secondary_id is not None:
#             # Using the primary_id as 1st argument create better entropy
#             # The same user with different link will get very different ids
#             args.append(secondary_id)
#         args.append(primary_id)
#         return self.hashids.encode(*args)
# 
#     def decode(self, short_id):
#         # we are reversing the order to respect primary first in the return
#         return self.hashids.decode(short_id)[::-1] # we use the step to ensure a tuple
# 
# Path: suma/core/services/file.py
# class LocalFileService(object):
#     def __init__(self, base_url, base_path):
#         suffix = ''
#         if not base_url.endswith('/'):
#             suffix = '/'
#         self.storage = LocalFileStorage(base_path, base_url + suffix)
# 
#     def create(self, data, filename, folder):
#         output = StringIO(data)
#         return self.storage.save_file(output, filename, folder)  # return final filename
# 
#     def url(self, filename):
#         return self.storage.url(filename)
# 
# class S3FileService(LocalFileService):
#     def __init__(self, base_url, bucket_name, access_key, secret_key):
#         suffix = ''
#         if not base_url.endswith('/'):
#             suffix = '/'
#         self.storage = S3FileStorage(
#             bucket_name=bucket_name,
#             base_url=base_url + suffix,
#             access_key=access_key,
#             secret_key=secret_key
#         )
# 
# Path: suma/core/services/task.py
# class TaskService(object):
#     def add_click(self, link_id, ip=None, referer=None):
#         assert type(link_id) in [IntType, LongType], "link_id is not an integer: %r" % link_id
#         tasks.add_click_task.apply_async((link_id, ip, referer), serializer='json')
# 
#     def get_link_data(self, link_id):
#         assert type(link_id) in [IntType, LongType], "link_id is not an integer: %r" % link_id
#         tasks.get_link_data_task.apply_async((link_id, ), serializer='json')


# Path: suma/common/services/factories.py
from suma.core.services import (
    LinkService,
    HashIdService,
    TaskService,
    S3FileService,
    LocalFileService
)
from paste.deploy.converters import asbool



def link_service_factory(context, request):
    dbsession = request.find_service(name='db', context=context)
    hashid = request.find_service(name='hashid', context=context)
    return LinkService(
        dbsession=dbsession,
        hashid=hashid,
    )


def hashid_service_factory(context, request):
    hashid_secret = request.registry.settings.get('hashid.secret')
    return HashIdService(
        secret=hashid_secret
    )



def task_service_factory(context, request):