Commit 87d6da92 authored by Melroy van den Berg's avatar Melroy van den Berg

switched to telnetutil

parent 19a14c5c
#https://addons.mozilla.org/en-US/firefox/addon/mozrepl/
from time import sleep
import mozrepl
import socket
NR_RETRIES=800 # 240 sec (4 min.)/ 0.3 sec
def load_page_blocking(url):
# telnet localhost 4242
try:
repl = mozrepl.Mozrepl()
except socket.error:
print "ERROR: Could not connect to Firefox. Did you install Mozrepl plugin in Firefox?\nIf so, did you also start the service. In the menu: Extra->Mozrepl->Start."
exit(1)
# Open url in current tab/window
repl.execute('content.location.href = \'' + url + '\'')
tries=0
while True:
# Get the page load state
state = repl.execute('document.readyState')
sleep(0.1)
if state == "complete":
# When completed wait a bit longer, in order to set repl again.
sleep(0.5)
break
tries+=1
if tries == NR_RETRIES:
print "ERROR: Too many retries. Do you have internet connection at all? Exit." # Time-out
exit(1)
# Set a temporally variable
repl.execute('content').document.temp=1
# Experimental
# repl.execute('content').document.hidden1 = repl.execute('content').document.createElement("input")
# repl.execute('content').document.hidden1.type = "hidden"
# repl.execute('content').document.hidden1.value = "abc"
# repl.execute('content').document.hidden1.name = "aaa"
# repl.execute('content').document.getElementById("syi-form").appendChild(document.hidden1)
# Polling until 'temp' is becoming undefined again, meaning it's back to creation content (context unloading)
while True:
temp = repl.execute('content').document.temp
if temp != 1:
# Form is submitted or page is closed, we continue!
break
else:
print "Form not yet submitted"
sleep(3)
#!/usr/bin/env python
import firefox
from mozrepl import Mozrepl
# https://www.marktplaats.nl/syi/201/228/plaatsAdvertentie.html?bucket=38&complete=true&origin=HEADER&l1=201&l2=228&title=Test&attribute[condition]=31&attribute[level]=1950&attribute[orientation]=1955&price.bidding=free-bidding&description=blah&price.value=25,50&acceptPaypal=true&attribute[delivery]=35&shippingDetails.price=650&shippingDetails.provider=postnl&shippingDetails.productCode=3000&shippingDetails.catalogName=parcels&shippingDetails.averageWeight=5000
......@@ -8,5 +8,7 @@ import firefox
# https://api.marktplaats.nl/v1/postnl/catalog
m = Mozrepl()
m.load_page_blocking("https://www.marktplaats.nl/syi/201/228/plaatsAdvertentie.html?bucket=38&origin=HEADER&title=")
m.close()
firefox.load_page_blocking("https://www.marktplaats.nl/syi/201/228/plaatsAdvertentie.html?bucket=38&origin=HEADER&title=")
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from __future__ import absolute_import
__title__ = 'mozrepl'
__version__ = '1.2.4'
__author__ = '별님'
__author_email__ = 'w7dn1ng75r@gmail.com'
__license__ = 'GPL v3'
__copyright__ = 'Copyright 2015 별님'
__url__ = 'https://github.com/Thestars3/pymozrepl/'
from .exception import Exception
from .mozrepl import Mozrepl
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import, division, print_function
import exceptions
#from ufp.terminal.debug import print_ as debug
class Exception(exceptions.Exception):
"""
mozrepl Firefox Add-on에서 반환한 오류에 대한 정보를 담는 클래스.
javascript Error 객체를 참조 하듯이 속성을 참조하십시오. 단, 메소드에 대한 참조는 지원하지 않습니다.
만약, 현재 객체에 존재하고 있는 이름과 같은 이름의 javascript object 속성에 접근하려면, __getitem__ 메소드를 사용하십시오.
특정 속성이 존재하는가를 검사하려면 __contains__ 메소드를 사용하십시오.
.. todo:: typeName, details 속성을 2.x 버전대에서 제거 할 것.
"""
def __init__(self, error):
self._error = error
self.typeName = self._error.get('name', '')
self.details = self._error.get('message', '')
message = self._error.get('message', '')
def __contains__(self, name):
if name in self._error:
return True
return False
def __getattr__(self, name):
if name in self._error:
return self._error[name]
raise AttributeError(b"{name} 속성이 존재하지 않습니다.".format(name=repr(name)))
def __getitem__(self, key):
if key in self._error:
return self._error[key]
raise KeyError(b"{key} 키가 존재하지 않습니다.".format(key=repr(key)))
def __str__(self):
msg = unicode()
if 'name' in self._error:
msg += '{name}: '.format(name=self._error['name'])
msg += self._error['message']
return msg
This diff is collapsed.
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from __future__ import absolute_import
from .object import Object
from .function import Function
from .array import Array
from .raw import Raw
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import, division, print_function
#from ufp.terminal.debug import print_ as debug
from .object import Object
class Array(Object):
"""
javascript array에 대한 인터페이스를 제공합니다.
__len__, __iter__ 메소드가 구현되어 있습니다.
.. todo:: __iter__ 메소드 사용시, 속성을 JSON.stringify 함수로 json으로 만들어두고 {type, value}, 가져올 수 있는 기본 타입(string, number, bool 등)은 그대로 둔다. 참조값이 존재하는 Object타입은 value에 참조값을 만들어 둔다.
사용 예는 다음과 같습니다.
.. code-block:: python
>>> import mozrepl
>>> repl = mozrepl.Mozrepl()
>>> array = repl.execute('[1,2,3,4,5,10]')
>>> len(array) # __len__
6
>>> list(array) # __iter__
[1, 2, 3, 4, 5, 10]
"""
def __init__(self, repl, uuid):
super(Array, self).__init__(repl, uuid)
def __len__(self):
buffer = '{reference}.length;'.format(
reference = self
)
return self._repl.execute(buffer)
def __iter__(self):
"""
javascript Object에 iterator하게 접근합니다.
:yield: value; 0 ~ 마지막 값까지 yield합니다.
"""
for index in range(len(self)):
buffer = '{reference}[{index}];'.format(
reference = self,
index = index
)
yield self._repl.execute(buffer)
raise StopIteration
\ No newline at end of file
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import, division, print_function
from .object import Object
class Function(Object):
"""
javascript function에 대한 인터페이스를 제공합니다.
사용 예는 다음과 같습니다.
.. code-block:: python
>>> import mozrepl
>>> repl = mozrepl.Mozrepl()
>>> func = repl.execute('(function(){ return "mozrepl"; })') #__call__
>>> func()
u'mozrepl'
>>> repl.execute('window').toString() #__call__
u'[object ChromeWindow]'
"""
def __init__(self, repl, uuid):
super(Function, self).__init__(repl, uuid)
def __repr__(self):
return 'function() {...}'
def __call__(self, *args):
"""
javascript Function object를 실행합니다.
입력하는 각 인자는 :py:func:`~mozrepl.util.convertToJs` 함수에서 허용하는 형식을 준수해야 합니다.
"""
buffer = map(convertToJs, args)
buffer = ', '.join(buffer)
buffer = '{reference}({args})'.format(reference=self, args=buffer)
return self._repl.execute(buffer)
from ..util import convertToJs
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import, division, print_function
#from ufp.terminal.debug import print_ as debug
import uuid
import json
from ..exception import Exception as MozException
class Object(object):
"""
javascript object에 대한 인터페이스를 제공합니다.
+ 사전 형식으로 속성에 접근할 수 있습니다(__getitem__, __setitem__, __delitem__).
+ 속성 형식으로 속성에 접근 할 수 있습니다(__getattr__, __setattr__, __delattr__).
+ __eq__, __contains__ 메소드가 구현되어 있습니다.
만약, 이 객체에 존재하는 속성의 이름과 같은 자바스크립트 오브젝트의 속성에 접근하려면, 사전 형식으로 원소에 접근하십시오.
사용 예는 다음과 같습니다.
.. code-block:: python
>>> import mozrepl
>>> repl = mozrepl.Mozrepl()
>>> a = repl.execute('repl')
>>> b = repl.execute('repl')
>>> a == b # __eq__
True
>>> '_name' in a # __contains__
True
>>> a._name # __getattr__
u'repl'
>>> a['_name'] # __getitem__
u'repl'
>>> a['_name'] = 'pymozrepl' # __setitem__
>>> a['_name']
u'pymozrepl'
>>> del a._name # __delattr__
>>> a._name
None
>>> for key, value in a: # __iter__
...
"""
def __init__(self, repl, uuid):
self.__dict__['_repl'] = repl
self.__dict__['_uuid'] = uuid
@classmethod
def makeNotinited(cls, repl):
"""
초기화되지 않은 참조 오브젝트를 얻습니다.
:param repl: mozrepl.Mozrepl 객체
:type repl: :py:class:`~mozrepl.Mozrepl`
:return: 초기화되지 않은 :py:class:`~mozrepl.type.Object` 객체.
:rtype: :py:class:`~mozrepl.type.Object`
"""
buffer= unicode(uuid.uuid4())
return cls(repl, buffer)
def __unicode__(self):
"""
자바스크립트에서 이 오브젝트에 대한 참조값.
만약, 자바스크립트에서 직접 이 오브젝트에 대해 접근하기를 원한다면, 이 속성을 통해 변수 이름을 얻을 수 있습니다. 예컨데, 다음과 같이 사용 할 수 있습니다.
.. code-block:: python
>>> import mozrepl
>>> repl = mozrepl.Mozrepl()
>>> obj = repl.execute('window')
>>> unicode(obj)
u'__pymozrepl_c8d7323280c54d09809e2dd7d34d1c70.ref["1e1c7ae3-c1fc-4664-b57f-1281bdc1c996"]'
>>> repl.execute('var value = {reference}'.format(reference=obj))
"""
return '{baseVar}.ref["{uuid}"]'.format(baseVar=self._repl._baseVarname, uuid=self._uuid)
def __eq__(self, other):
buffer = '{other} == {reference};'.format(other=convertToJs(other), reference=self)
return self._repl.execute(buffer)
def __contains__(self, item):
buffer = '{item} in {reference};'.format(item=convertToJs(item), reference=self)
return self._repl.execute(buffer)
def __getattr__(self, name):
return self[name]
def __setattr__(self, name, value):
self[name] = value
def __delattr__(self, name):
del self[name]
def __iter__(self):
"""
javascript Object에 iterator하게 접근합니다.
:yield: value; 오브젝트에 '__iterator__' 속성이 존재한다면, Iterator를 사용하여 작업을 수행합니다.
:yield: 별도의 이터레이터가 정의되어 있지 않다면, (key, value) 쌍을 전달합니다.
"""
buffer = """(function(reference){{ var processValue = function(value){{ var type = typeof value; if ( type == 'object' || type == 'function' ) {{ if ( type == 'object' && Array.isArray(value) ) {{ type = 'array'; }}; var uuid = {baseVar}.modules.uuid.uuid(); {baseVar}.ref[uuid] = value; return {{ 'uuid' : uuid.toString(), 'type' : type }}; }}; return {{ 'value' : value }}; }}; let iter; if ( '__iterator__' in reference ) {{ iter = function* (){{ for (let value in Iterator(reference)) {{ let robj = [ processValue(value) ]; yield JSON.stringify(robj); }}; }}; }} else {{ iter = function* (){{ for (let [key, value] in Iterator(reference)) {{ let robj = [ processValue(key), processValue(value) ]; yield JSON.stringify(robj); }}; }}; }}; return {{ 'iter': iter(), 'next': function(){{ let buffer = this.iter.next(); if ( buffer.done ) {{ throw {{ 'name': 'StopIteration' }}; }}; return buffer.value; }} }}; }}({reference}));""".format(
reference = self,
baseVar = self._repl._baseVarname
)
iter = self._repl.execute(buffer)
while True:
try:
robj = self._repl.execute('{iter}.next();'.format(iter=iter))
except MozException, e:
if 'name' in e and e.name == 'StopIteration':
raise StopIteration
raise e
items = list()
robj = json.loads(robj, strict=False)
for item in robj:
if 'type' in item:
if item['type'] == 'object':
items.append( Object(self._repl, item['uuid']) )
elif item['type'] == 'array':
items.append( Array(self._repl, item['uuid']) )
elif item['type'] == 'function':
items.append( Function(self._repl, item['uuid']) )
else:
items.append(item.get('value', None))
if len(items) == 1:
yield items[0]
else:
yield tuple(items)
pass
def __repr__(self):
buffer = """{baseVar}.modules.represent({reference});""".format(
reference = self,
baseVar = self._repl._baseVarname
)
return self._repl.execute(buffer)
def __getitem__(self, key):
key = convertToJs(key)
buffer = '{reference}[{key}]'.format(reference=self, key=key)
item = self._repl.execute(buffer)
if isinstance(item, Function):
buffer = '{reference}[{key}].bind({reference})'.format(reference=self, key=key)
item = self._repl.execute(buffer)
return item
def __setitem__(self, key, value):
buffer = '{reference}[{key}] = {value}; null;'.format(reference=self, key=convertToJs(key), value=value)
self._repl._rawExecute(buffer)
def __delitem__(self, key):
buffer = 'delete {reference}[{key}]; null;'.format(reference=self, key=convertToJs(key))
self._repl._rawExecute(buffer)
def __del__(self):
buffer = 'delete {reference}; null;'.format(reference=self)
self._repl._rawExecute(buffer)
from .array import Array
from .function import Function
from ..util import convertToJs
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import, division, print_function
class Raw():
"""
자바스크립트 코드를 담는 클래스.
이 클래스로 생성된 코드는 :py:func:`~mozrepl.util.convertToJs` 함수에 의해 변환되지 않고, 입력된 그대로 전달되게 됩니다.
:param code: 자바스크립트 코드.
:type code: unicode
"""
def __init__(self, code):
self.code = code
def __unicode__(self):
return self.code
\ No newline at end of file
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import, division, print_function
import cookielib
import json
#from ufp.terminal.debug import print_ as debug
class _JsonEncoder(json.JSONEncoder):
def __init__(self, *args, **kwargs):
super(_JsonEncoder, self).__init__(*args, **kwargs)
from .type import Raw, Object
self.types = {
'Raw': Raw,
'Object': Object
}
def default(self, obj):
if isinstance(obj, self.types['Object']):
return unicode(obj)
if isinstance(obj, self.types['Raw']):
return unicode(obj)
return super(_JsonEncoder, self).default(obj)
def convertToJs(obj):
"""
입력받은 값을 javascript에서 사용 가능한 값으로 변환합니다.
:param obj: 변환할 값. 만약 list와 tuple타입을 인자로 준다면, 포함된 값은 :py:func:`~mozrepl.util.convertToJs` 함수가 변환 할 수 있는 값이어야 합니다.
:type obj: :py:class:`~mozrepl.type.Object`, :py:class:`~mozrepl.type.Function`, :py:class:`~mozrepl.type.Array`, :py:class:`~mozrepl.type.Raw` 외 python 기본 타입.
:return: JSON string
:rtype: unicode
"""
buffer = json.dumps(obj, cls=_JsonEncoder)
return unicode(buffer)
def openTab(repl, url, isPrivate=False, inNewWindow=False, inBackground=False, isPinned=False):
"""
Opens a new tab. The new tab will open in the active window or in a new window, depending on the inNewWindow option.
:param repl: mozrepl 객체.
:type repl: :py:class:`~mozrepl.Mozrepl`
:param url: String URL to be opened in the new tab. This is a required property.
:type url: unicode
:param isPrivate: bool which will determine whether the new tab should be private or not. If your add-on does not support private browsing this will have no effect. See the private-browsing documentation for more information. Defaults to false.
:type isPrivate: bool
:param inNewWindow: If present and true, a new browser window will be opened and the URL will be opened in the first tab in that window. This is an optional property.
:type inNewWindow: bool
:param inBackground: If present and true, the new tab will be opened to the right of the active tab and will not be active. This is an optional property.
:type inBackground: bool
:param isPinned: If present and true, then the new tab will be pinned as an app tab.
:type isPinned: bool
"""
buffer = """{baseVar}.modules.require('sdk/tabs').open({{ url: {url}, isPrivate: {isPrivate}, inNewWindow: {inNewWindow}, inBackground: {inBackground}, isPinned: {isPinned} }});""".format(
baseVar = repl._baseVarname,
url = convertToJs(url),
isPrivate = convertToJs(isPrivate),
inNewWindow = convertToJs(isPrivate),
inBackground = convertToJs(inBackground),
isPinned = convertToJs(isPinned)
)
tabs = repl.execute(buffer)
def getAllTabs(repl) :
"""
접속한 브라우져에 존재하는 모든 탭 오브젝트를 가져옵니다.
:param repl: mozrepl 객체.
:type repl: :py:class:`~mozrepl.Mozrepl`
:yield: 각 탭 :py:class:`~mozrepl.type.Object` 객체.
"""
buffer = """{baseVar}.modules.require('sdk/tabs');""".format(
baseVar = repl._baseVarname
)
tabs = repl.execute(buffer)
for tab in tabs:
yield tab
pass
def getCookiesFromHost(repl, host):
"""
Returns an generator of cookies that would be returned to a given host, ignoring the cookie flags isDomain, isSecure, and isHttpOnly. Therefore, if the specified host is "weather.yahoo.com", host or domain cookies for "weather.yahoo.com" and "yahoo.com" would both be returned, while a cookie for "my.weather.yahoo.com" would not.
:param repl: mozrepl.Mozrepl 객체
:type repl: :py:class:`~mozrepl.Mozrepl`
:param host: The host unicode string to look for, such as "google.com". This should consist only of the host portion of the URI and should not contain a leading dot, port number, or other information.
:type host: unicode
:yield: An cookielib.Cookie objects representing the matching cookies.
"""
from .type import Object
iter = Object.makeNotinited(repl)
repl._rawExecute(
"""
{iter} = {baseVar}.modules.Services.cookies.getCookiesFromHost({host});
null;
""".format(
iter=iter,
baseVar=repl._baseVarname,
host=convertToJs(host)
)
)
while repl.execute('{iter}.hasMoreElements()'.format(iter=iter)):
buffer = repl.execute(
"""
let {{Ci}} = {baseVar}.modules.require("chrome");
let buffer = {iter}.getNext().QueryInterface(Ci.nsICookie);
JSON.stringify(buffer);
""".format(
iter = iter,
baseVar = repl._baseVarname
)
)
cookie = json.loads(buffer)
domain = cookie.get('host', None)
initial_dot = domain.startswith(".")
expires = cookie.get('expires', None)
if expires == 0:
expires = None
yield cookielib.Cookie(
0,
cookie.get('name', None),
cookie.get('value', None),
None,
False,
domain,
cookie.get('isDomain', None),
initial_dot,
cookie.get('path', None),
False,
cookie.get('isSecure', None),
expires,
cookie.get('isSession', None),
None,
None,
{}
)
pass
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment