<commit_before>import json
import httplib
import urllib2
from contextlib import closing

from tg import config
from pylons import c, request

from pyforge import model as M
from pyforge.lib.security import roles_with_project_access
from . import exceptions as sfx_exc

def read_response(response, *expected):
    if not expected: expected = (200,)
    text = response.read()
    if response.status in expected:
        try:
            return json.loads(text)
        except ValueError:
            return text
    cls = sfx_exc.SFXAPIError.status_map.get(response.status, sfx_exc.SFXAPIError)
    raise cls('Error status %s' % response.status, text)

class SFXUserApi(object):
    
    def __init__(self):
        self.project_host = config.get('sfx.api.host', None)
        self.project_path = config.get('sfx.api.project_path', '/api/user')

    def _username_api_url(self, username):
        return 'http://%s/api/user/username/%s/json' % (
            self.project_host or request.host,
            username)

    def _userid_api_url(self, id):
        return 'http://%s/api/user/id/%s/json' % (
            self.project_host or request.host,
            id)

    def user_data(self, username, timeout=2):
        """
        given a sfnet hostname and userid, returns a dict of user data
        """
        try:
            url = self._userid_api_url(int(username))
        except ValueError:
            url = self._username_api_url(username)
        try:
            url_handle = urllib2.urlopen(url, timeout=timeout)
            return json.load(url_handle)['User']
        except urllib2.HTTPError, ex:
            if ex.code == 404: return None
            raise

    def upsert_user(self, username, user_data=None):
        u = M.User.query.get(username=username)
        if user_data is None:
            if u is not None and u.sfx_userid:
                user_data = self.user_data(u.sfx_userid)
            else:
                user_data = self.user_data(username)
        if u is None:
            if user_data is None: return None
            u = M.User(
                username=username,
                display_name=user_data['name'],
                sfx_userid=user_data['id'])
            n = M.Neighborhood.query.get(name='Users')
            n.register_project('u/' + u.username.replace('_', '-'), u, user_project=True)
        if user_data is None: return u
        if u.display_name != user_data['name']:
            u.display_name = user_data['name']
        if u.sfx_userid != user_data['id']:
            u.sfx_userid = user_data['id']
        return u

class SFXProjectApi(object):

    def __init__(self):
        self.project_host = config.get('sfx.api.host', None)
        self.project_path = config.get('sfx.api.project_path', '/api/project')

    def _connect(self):
        return closing(httplib.HTTPConnection(self.project_host or request.host))

    def _unix_group_name(self, neighborhood, shortname):
        if neighborhood.url_prefix == '/p/':
            path = shortname
        else:
            path = neighborhood.url_prefix + shortname[len(neighborhood.shortname_prefix):]
        parts = [ p for p in path.split('/') if p ]
        return '.'.join(reversed(parts))

    def create(self, user, neighborhood, shortname, short_description='No description'):
        with self._connect() as conn:
            ug_name = self._unix_group_name(neighborhood, shortname)
            args = dict(
                user_id=user.sfx_userid,
                unix_group_name=ug_name,
                group_name=shortname,
                short_description=short_description)
            conn.request('POST', self.project_path, json.dumps(args))
            response = conn.getresponse()
            return read_response(response, 201)

    def read(self, p):
        with self._connect() as conn:
            ug_name = self._unix_group_name(p.neighborhood, p.shortname)
            conn.request('GET', self.project_path + '/name/' + ug_name + '/json')
            response = conn.getresponse()<commit_msg>[#524] - updated logic to convert between SFX project names and allura<commit_after>import json
import httplib
import urllib2
from contextlib import closing

from tg import config
from pylons import c, request

from pyforge import model as M
from pyforge.lib.security import roles_with_project_access
from . import exceptions as sfx_exc

def read_response(response, *expected):
    if not expected: expected = (200,)
    text = response.read()
    if response.status in expected:
        try:
            return json.loads(text)
        except ValueError:
            return text
    cls = sfx_exc.SFXAPIError.status_map.get(response.status, sfx_exc.SFXAPIError)
    raise cls('Error status %s' % response.status, text)

class SFXUserApi(object):
    
    def __init__(self):
        self.project_host = config.get('sfx.api.host', None)
        self.project_path = config.get('sfx.api.project_path', '/api/user')

    def _username_api_url(self, username):
        return 'http://%s/api/user/username/%s/json' % (
            self.project_host or request.host,
            username)

    def _userid_api_url(self, id):
        return 'http://%s/api/user/id/%s/json' % (
            self.project_host or request.host,
            id)

    def user_data(self, username, timeout=2):
        """
        given a sfnet hostname and userid, returns a dict of user data
        """
        try:
            url = self._userid_api_url(int(username))
        except ValueError:
            url = self._username_api_url(username)
        try:
            url_handle = urllib2.urlopen(url, timeout=timeout)
            return json.load(url_handle)['User']
        except urllib2.HTTPError, ex:
            if ex.code == 404: return None
            raise

    def upsert_user(self, username, user_data=None):
        u = M.User.query.get(username=username)
        if user_data is None:
            if u is not None and u.sfx_userid:
                user_data = self.user_data(u.sfx_userid)
            else:
                user_data = self.user_data(username)
        if u is None:
            if user_data is None: return None
            u = M.User(
                username=username,
                display_name=user_data['name'],
                sfx_userid=user_data['id'])
            n = M.Neighborhood.query.get(name='Users')
            n.register_project('u/' + u.username.replace('_', '-'), u, user_project=True)
        if user_data is None: return u
        if u.display_name != user_data['name']:
            u.display_name = user_data['name']
        if u.sfx_userid != user_data['id']:
            u.sfx_userid = user_data['id']
        return u

class SFXProjectApi(object):

    def __init__(self):
        self.project_host = config.get('sfx.api.host', None)
        self.project_path = config.get('sfx.api.project_path', '/api/project')

    def _connect(self):
        return closing(httplib.HTTPConnection(self.project_host or request.host))

    def _unix_group_name(self, neighborhood, shortname):
        path = neighborhood.url_prefix + shortname[len(neighborhood.shortname_prefix):]
        parts = [ p for p in path.split('/') if p ]
        if len(parts) == 2 and parts[0] == 'p':
            parts = parts[1:]
        return '.'.join(reversed(parts))

    def create(self, user, neighborhood, shortname, short_description='No description'):
        with self._connect() as conn:
            ug_name = self._unix_group_name(neighborhood, shortname)
            args = dict(
                user_id=user.sfx_userid,
                unix_group_name=ug_name,
                group_name=shortname,
                short_description=short_description)
            conn.request('POST', self.project_path, json.dumps(args))
            response = conn.getresponse()
            return read_response(response, 201)

    def read(self, p):
        with self._connect() as conn:
            ug_name = self._unix_group_name(p.neighborhood, p.shortname)
            conn.request('GET', self.project_path + '/name/' + ug_name + '/json')
            response = conn.getresponse()
{'fraction_non_alphanumeric': 0.10766580534022395, 'fraction_numerical': 0.003937492309585333, 'mean_word_length': 2.2787414279951594, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6598464', 'n_tokens_mistral': 2494, 'n_tokens_neox': 2424, 'n_words': 561}