def generate_short_url(original_url): """ Sharding is a must if this TinyUrlService need to support high concurrency :param original_url: :return: """ session = DBSession() short_url_in_db = session.query(ShortUrl).filter( ShortUrl.original_url == original_url).first() if short_url_in_db: short_id = short_url_in_db.id hash_str = utils.encode_base64(short_id) return hash_str short_url = ShortUrl() short_url.original_url = original_url current = datetime.datetime.now() short_url.createdTime = current short_url.updatedTime = current try: session.add(short_url) session.commit() short_id = short_url.id hash_str = utils.encode_base64(short_id) session.query(ShortUrl).filter(ShortUrl.id == short_id).update( {"short_url": hash_str}) session.commit() session.close() return hash_str except Exception as e: logging.error('ERROR generate_short_url url:%s,error:%s' % (original_url, e))
def test_when_user_has_many_urls_created(self): login_user(self.client, self.user) ShortUrl(original_url='http://test.pl', slug='test', user_id=str(self.user.id)).save() ShortUrl(original_url='http://test2.pl', slug='test2', user_id=str(self.user.id)).save() response = self.client.get(self.ENDPOINT) self.assertEqual( response.json, { 'URLs': [{ 'slug': 'test', 'original_url': 'http://test.pl', 'created': '2017-02-01T12:00:00+00:00', 'access_counter': 0 }, { 'slug': 'test2', 'original_url': 'http://test2.pl', 'created': '2017-02-01T12:00:00+00:00', 'access_counter': 0 }] })
def test_when_duplicated_slug_in_db(self): slug = 'test' ShortUrl(original_url='http://test.pl', slug=slug).save() ShortUrl(original_url='http://test2.pl', slug=slug).save() response = self.client.get(self.ENDPOINT_TEMPLATE.format(slug)) self.assertEqual(response.status_code, 500)
def generate_short_url(): """ .. :quickref: ShortUrl; Generate short url. Generate short url for original url given by user using custom slug if specified. :reqheader Accept: application/json :<json string original_url: url of website to be shorten :<json string slug: (optional) slug to use in shortened url :resheader Content-Type: application/json :>json string short_url: short url which redirects to original url :status 201: ShortUrl created :status 500: slug already exists in db """ url_data = RegisterUrlSchema().load(request.get_json()).data url_data['user_id'] = str(current_user.id) short_url_obj = ShortUrl(**url_data) if 'slug' in url_data: if ShortUrl.objects(slug=short_url_obj.slug): log.error('Slug already exists in database') raise SlugAlreadyExistsException() else: slug = generate_random_slug(length=6) while ShortUrl.objects(slug=slug): log.warning('Slug duplicate detected! - {}'.format(slug)) slug = generate_random_slug(length=6) short_url_obj.slug = slug short_url_obj.save() short_url = url_for('main.get_url', slug=short_url_obj.slug, _external=True) return make_response(jsonify(dict(short_url=short_url)), CREATED)
def long2short(self, request): if request.method == 'POST': url = request.POST.get('url') user_id = request.POST.get('userId') is_good = utils.is_good_url(url) # 检查url if not is_good: return mhttp.params_error(message='URL不合法') # 检查url是否已经生成过 objs = ShortUrl.objects.all().filter(url=url, is_active=True, user=user_id, is_delete=False) if len(objs) > 0: return mhttp.result( data={ 'url': constant.shorturl_prefix + objs[0].short_code }) # 生成短码 while True: short_code = utils.random_str(size=4) objs = ShortUrl.objects.all().filter(short_code=short_code, is_active=True) if len(objs) == 0: break # 存储 shortUrl = ShortUrl() shortUrl.url = url shortUrl.short_code = short_code shortUrl.user = User.objects.get(id=user_id) shortUrl.save() return mhttp.result( data={'url': constant.shorturl_prefix + short_code})
def test_when_non_unique_slug_specified(self): login_user(self.client, self.user) new_user = User() new_user.save() ShortUrl(original_url='http://test.pl', slug='test_slug', user_id=str(new_user.id)).save() url_data = dict(original_url='http://destination.pl', slug='test_slug') response = self.client.post(self.ENDPOINT, data=url_data) self.assertEqual(response.status_code, 500) short_links = ShortUrl.objects() self.assertEqual(len(short_links), 1) short_link = short_links[0] self.assertEqual(short_link.original_url, 'http://test.pl') self.assertEqual(short_link.user_id, str(new_user.id)) self.assertEqual(short_link.slug, 'test_slug')
def test_when_slug_in_db(self): slug = 'test' ShortUrl(original_url='http://test.pl', slug=slug, access_counter=0).save() response = self.client.get(self.ENDPOINT_TEMPLATE.format(slug)) short_url = ShortUrl.objects.get(slug=slug) self.assertEqual(short_url.access_counter, 1) self.assertEqual(response.status_code, 302) self.assertEqual(response.headers['location'], 'http://test.pl')
def test_when_slug_in_db_but_other_user_is_slug_owner(self): login_user(self.client, self.user) other_user = User() other_user.save() slug = 'test' ShortUrl(original_url='http://test.pl', slug=slug, user_id=str(other_user.id)).save() response = self.client.get(self.ENDPOINT_TEMPLATE.format(slug)) self.assertEqual(response.status_code, 401)
def get_list_of_user_urls(): """ .. :quickref: ShortUrl; Get info about user`s short urls. Return details about short urls generated by current user. :resheader Content-Type: application/json :>json list[url_info] URLs: list of dicts with details about short url :status 200: query to database succeeded """ short_links = ShortUrl.objects(user_id=str(current_user.id)) return jsonify({'URLs': ShortUrlSchema(many=True).dump(short_links).data})
def get_url(slug): """ .. :quickref: ShortUrl; Get original url. Redirect to original url for given slug. :param slug: short string which was created during generation short url :status 302: ShortUrl for given slug found and redirect is performed :status 404: ShortUrl for given slug not found :status 500: multiple ShortUrls for given slug found """ try: # FIXME: update can raise different exceptions ShortUrl.objects(slug=slug).update(inc__access_counter=1) short_link = ShortUrl.objects.get(slug=slug) return redirect(short_link.original_url) except DoesNotExist as e: log.error(e) raise NotFound() except MultipleObjectsReturned as e: log.error(e) raise InternalServerError()
def test_when_only_original_url_specified_and_generated_slug_already_exist( self, generate_random_slug_mock): login_user(self.client, self.user) generate_random_slug_mock.side_effect = ['test_slug', 'new_slug'] ShortUrl(original_url='http://test.pl', slug='test_slug').save() url_data = dict(original_url='http://destination.pl') short_links = ShortUrl.objects() self.assertEqual(len(short_links), 1) response = self.client.post(self.ENDPOINT, data=url_data) self.assertEqual(response.status_code, 201) self.assertDictEqual(response.json, dict(short_url='http://localhost:5001/new_slug')) short_links = ShortUrl.objects(slug__ne='test_slug') self.assertEqual(len(short_links), 1) short_link = short_links[0] self.assertEqual(short_link.original_url, 'http://destination.pl') self.assertEqual(short_link.slug, 'new_slug') self.assertEqual(short_link.user_id, str(self.user.id)) self.assertEqual(short_link.access_counter, 0) self.assertEqual(short_link.created, datetime.datetime(2017, 2, 1, 12, 0, tzinfo=tzutc()))
def test_when_unique_slug_specified(self): login_user(self.client, self.user) url_data = dict(original_url='http://destination.pl', slug='test_slug') response = self.client.post(self.ENDPOINT, data=url_data) self.assertEqual(response.status_code, 201) self.assertDictEqual(response.json, dict(short_url='http://localhost:5001/test_slug')) short_links = ShortUrl.objects() self.assertEqual(len(short_links), 1) short_link = short_links[0] self.assertEqual(short_link.original_url, 'http://destination.pl') self.assertEqual(short_link.slug, 'test_slug') self.assertEqual(short_link.user_id, str(self.user.id)) self.assertEqual(short_link.access_counter, 0) self.assertEqual(short_link.created, datetime.datetime(2017, 2, 1, 12, 0, tzinfo=tzutc()))
def index(): form = UrlForm() # Does all of the form processing work. # Returns true if nothing went wrong retrieving the data. if form.validate_on_submit(): if is_valid_url(form.url.data): shortlink = generate_shortlink() shorturl = ShortUrl(shortlink=shortlink, link=form.url.data) db.session.add(shorturl) db.session.commit() flash('Request to shorten URL {}'.format(form.url.data)) flash('At extension {}'.format(shortlink)) return redirect(url_for('results', link=shortlink)) else: flash('Request to shorten URL {} failed'.format(form.url.data)) return redirect(url_for('results')) return render_template('index.html', form=form)
def test_when_slug_in_db_and_user_is_its_owner(self): login_user(self.client, self.user) slug = 'test' ShortUrl( original_url='http://test.pl', slug=slug, user_id=str(self.user.id), ).save() response = self.client.get(self.ENDPOINT_TEMPLATE.format(slug)) response.json['created'] = parser.parse(response.json['created']) self.assertEqual(response.status_code, 200) self.assertDictEqual( response.json, dict(original_url='http://test.pl', created=datetime.datetime(2017, 2, 1, 12, 0, 0, tzinfo=tzutc()), access_counter=0))