├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── assets
├── logo.png
├── logo.svg
└── waydroidstop.jpg
├── clickable.yaml
├── deps
├── pexpect
│ ├── ANSI.py
│ ├── FSM.py
│ ├── __init__.py
│ ├── _async.py
│ ├── bashrc.sh
│ ├── exceptions.py
│ ├── expect.py
│ ├── fdpexpect.py
│ ├── popen_spawn.py
│ ├── pty_spawn.py
│ ├── pxssh.py
│ ├── replwrap.py
│ ├── run.py
│ ├── screen.py
│ ├── spawnbase.py
│ └── utils.py
└── ptyprocess
│ ├── __init__.py
│ ├── _fork_pty.py
│ ├── ptyprocess.py
│ └── util.py
├── manifest.json.in
├── po
├── CMakeLists.txt
├── de.po
├── fr.po
├── nl.po
├── pt_PT.po
└── waydroidhelper.aaronhafer.pot
├── qml
├── About.qml
├── Installer.qml
├── Main.qml
├── PasswordPrompt.qml
├── Uninstaller.qml
└── modules
│ └── CenteredLabel.qml
├── src
├── __init__.py
├── installer.py
├── main.py
├── pam.py
├── password_type.py
└── waydroid-custom-init
├── waydroidhelper.apparmor
└── waydroidhelper.desktop.in
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Marcel Alexandru Nitan
2 | # https://github.com/nitanmarcel/cinny-click-packaging/blob/main/.github/workflows/build.yml
3 |
4 | name: Clickable Build
5 |
6 | on: [ push, pull_request ]
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v3
14 | - name: Install clickable
15 | run: |
16 | python3 -m pip install clickable-ut
17 | - name: Build
18 | run: |
19 | clickable build
20 | - name: Upload Artifacts
21 | uses: actions/upload-artifact@v3
22 | with:
23 | name: waydroid_helper_UNCONFINED
24 | path: build/all/app/*.click
25 | if-no-files-found: error
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.0)
2 | project(waydroidhelper C CXX)
3 |
4 | # Automatically create moc files
5 | set(CMAKE_AUTOMOC ON)
6 |
7 | execute_process(
8 | COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH
9 | OUTPUT_VARIABLE ARCH_TRIPLET
10 | OUTPUT_STRIP_TRAILING_WHITESPACE
11 | )
12 | set(QT_IMPORTS_DIR "lib/${ARCH_TRIPLET}")
13 |
14 | set(PROJECT_NAME "waydroidhelper")
15 | set(FULL_PROJECT_NAME "waydroidhelper.aaronhafer")
16 | set(DATA_DIR /)
17 | set(DESKTOP_FILE_NAME ${PROJECT_NAME}.desktop)
18 |
19 | # This command figures out the minimum SDK framework for use in the manifest
20 | # file via the environment variable provided by Clickable or sets a default value otherwise.
21 | if(DEFINED ENV{SDK_FRAMEWORK})
22 | set(CLICK_FRAMEWORK "$ENV{SDK_FRAMEWORK}")
23 | else()
24 | set(CLICK_FRAMEWORK "ubuntu-sdk-16.04.3")
25 | endif()
26 |
27 | # This figures out the target architecture for use in the manifest file.
28 | if(DEFINED ENV{ARCH})
29 | set(CLICK_ARCH "$ENV{ARCH}")
30 | else()
31 | execute_process(
32 | COMMAND dpkg-architecture -qDEB_HOST_ARCH
33 | OUTPUT_VARIABLE CLICK_ARCH
34 | OUTPUT_STRIP_TRAILING_WHITESPACE
35 | )
36 | endif()
37 |
38 | configure_file(manifest.json.in ${CMAKE_CURRENT_BINARY_DIR}/manifest.json)
39 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/manifest.json DESTINATION ${CMAKE_INSTALL_PREFIX})
40 | install(FILES ${PROJECT_NAME}.apparmor DESTINATION ${DATA_DIR})
41 |
42 | install(DIRECTORY assets DESTINATION ${DATA_DIR})
43 | install(DIRECTORY src DESTINATION ${DATA_DIR})
44 |
45 | install(DIRECTORY qml DESTINATION ${DATA_DIR})
46 | install(DIRECTORY deps DESTINATION ${DATA_DIR})
47 | # Translations
48 | file(GLOB_RECURSE I18N_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/po qml/*.qml qml/*.js)
49 | list(APPEND I18N_SRC_FILES ${DESKTOP_FILE_NAME}.in.h)
50 |
51 | find_program(INTLTOOL_MERGE intltool-merge)
52 | if(NOT INTLTOOL_MERGE)
53 | message(FATAL_ERROR "Could not find intltool-merge, please install the intltool package")
54 | endif()
55 | find_program(INTLTOOL_EXTRACT intltool-extract)
56 | if(NOT INTLTOOL_EXTRACT)
57 | message(FATAL_ERROR "Could not find intltool-extract, please install the intltool package")
58 | endif()
59 |
60 | add_custom_target(${DESKTOP_FILE_NAME} ALL
61 | COMMENT "Merging translations into ${DESKTOP_FILE_NAME}..."
62 | COMMAND LC_ALL=C ${INTLTOOL_MERGE} -d -u ${CMAKE_SOURCE_DIR}/po ${CMAKE_SOURCE_DIR}/${DESKTOP_FILE_NAME}.in ${DESKTOP_FILE_NAME}
63 | COMMAND sed -i 's/${PROJECT_NAME}-//g' ${CMAKE_CURRENT_BINARY_DIR}/${DESKTOP_FILE_NAME}
64 | )
65 |
66 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${DESKTOP_FILE_NAME} DESTINATION ${DATA_DIR})
67 |
68 | add_subdirectory(po)
69 |
70 | # Make source files visible in qtcreator
71 | file(GLOB_RECURSE PROJECT_SRC_FILES
72 | RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
73 | qml/*.qml
74 | qml/*.js
75 | src/*
76 | deps/*
77 | *.json
78 | *.json.in
79 | *.apparmor
80 | *.desktop.in
81 | )
82 |
83 | add_custom_target(${PROJECT_NAME}_FILES ALL SOURCES ${PROJECT_SRC_FILES})
84 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Waydroid Helper
2 |
3 | A collection of tools that help you to use Waydroid on UbuntuTouch.
4 | Current features:
5 | * Install/Uninstall WayDroid
6 | * Hide unwanted apps
7 | * A "Stop App"
8 | * Access to help resources
9 |
10 | Translations can be submitted here: https://poeditor.com/join/project?hash=DIES6h7HNF
11 |
12 | Donations: https://www.paypal.com/paypalme/AaronTheIssueGuy
13 |
14 | ## License
15 |
16 | Copyright (C) 2021-2022 Aaron Hafer
17 |
18 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published
19 | by the Free Software Foundation.
20 |
21 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
22 |
23 | You should have received a copy of the GNU General Public License along with this program. If not, see .
24 |
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aarontheissueguy/WaydroidHelper/26800434fb1be15a5bd87cfa5ec31be2f03aaf21/assets/logo.png
--------------------------------------------------------------------------------
/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
25 |
--------------------------------------------------------------------------------
/assets/waydroidstop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aarontheissueguy/WaydroidHelper/26800434fb1be15a5bd87cfa5ec31be2f03aaf21/assets/waydroidstop.jpg
--------------------------------------------------------------------------------
/clickable.yaml:
--------------------------------------------------------------------------------
1 | clickable_minimum_required: 6.22.0
2 | builder: pure-qml-cmake
3 | kill: qmlscene
4 | skip_review: true
5 | framework: ubuntu-sdk-20.04
6 |
--------------------------------------------------------------------------------
/deps/pexpect/ANSI.py:
--------------------------------------------------------------------------------
1 | '''This implements an ANSI (VT100) terminal emulator as a subclass of screen.
2 |
3 | PEXPECT LICENSE
4 |
5 | This license is approved by the OSI and FSF as GPL-compatible.
6 | http://opensource.org/licenses/isc-license.txt
7 |
8 | Copyright (c) 2012, Noah Spurrier
9 | PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
10 | PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
11 | COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
12 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 |
20 | '''
21 |
22 | # references:
23 | # http://en.wikipedia.org/wiki/ANSI_escape_code
24 | # http://www.retards.org/terminals/vt102.html
25 | # http://vt100.net/docs/vt102-ug/contents.html
26 | # http://vt100.net/docs/vt220-rm/
27 | # http://www.termsys.demon.co.uk/vtansi.htm
28 |
29 | from . import screen
30 | from . import FSM
31 | import string
32 |
33 | #
34 | # The 'Do.*' functions are helper functions for the ANSI class.
35 | #
36 | def DoEmit (fsm):
37 |
38 | screen = fsm.memory[0]
39 | screen.write_ch(fsm.input_symbol)
40 |
41 | def DoStartNumber (fsm):
42 |
43 | fsm.memory.append (fsm.input_symbol)
44 |
45 | def DoBuildNumber (fsm):
46 |
47 | ns = fsm.memory.pop()
48 | ns = ns + fsm.input_symbol
49 | fsm.memory.append (ns)
50 |
51 | def DoBackOne (fsm):
52 |
53 | screen = fsm.memory[0]
54 | screen.cursor_back ()
55 |
56 | def DoBack (fsm):
57 |
58 | count = int(fsm.memory.pop())
59 | screen = fsm.memory[0]
60 | screen.cursor_back (count)
61 |
62 | def DoDownOne (fsm):
63 |
64 | screen = fsm.memory[0]
65 | screen.cursor_down ()
66 |
67 | def DoDown (fsm):
68 |
69 | count = int(fsm.memory.pop())
70 | screen = fsm.memory[0]
71 | screen.cursor_down (count)
72 |
73 | def DoForwardOne (fsm):
74 |
75 | screen = fsm.memory[0]
76 | screen.cursor_forward ()
77 |
78 | def DoForward (fsm):
79 |
80 | count = int(fsm.memory.pop())
81 | screen = fsm.memory[0]
82 | screen.cursor_forward (count)
83 |
84 | def DoUpReverse (fsm):
85 |
86 | screen = fsm.memory[0]
87 | screen.cursor_up_reverse()
88 |
89 | def DoUpOne (fsm):
90 |
91 | screen = fsm.memory[0]
92 | screen.cursor_up ()
93 |
94 | def DoUp (fsm):
95 |
96 | count = int(fsm.memory.pop())
97 | screen = fsm.memory[0]
98 | screen.cursor_up (count)
99 |
100 | def DoHome (fsm):
101 |
102 | c = int(fsm.memory.pop())
103 | r = int(fsm.memory.pop())
104 | screen = fsm.memory[0]
105 | screen.cursor_home (r,c)
106 |
107 | def DoHomeOrigin (fsm):
108 |
109 | c = 1
110 | r = 1
111 | screen = fsm.memory[0]
112 | screen.cursor_home (r,c)
113 |
114 | def DoEraseDown (fsm):
115 |
116 | screen = fsm.memory[0]
117 | screen.erase_down()
118 |
119 | def DoErase (fsm):
120 |
121 | arg = int(fsm.memory.pop())
122 | screen = fsm.memory[0]
123 | if arg == 0:
124 | screen.erase_down()
125 | elif arg == 1:
126 | screen.erase_up()
127 | elif arg == 2:
128 | screen.erase_screen()
129 |
130 | def DoEraseEndOfLine (fsm):
131 |
132 | screen = fsm.memory[0]
133 | screen.erase_end_of_line()
134 |
135 | def DoEraseLine (fsm):
136 |
137 | arg = int(fsm.memory.pop())
138 | screen = fsm.memory[0]
139 | if arg == 0:
140 | screen.erase_end_of_line()
141 | elif arg == 1:
142 | screen.erase_start_of_line()
143 | elif arg == 2:
144 | screen.erase_line()
145 |
146 | def DoEnableScroll (fsm):
147 |
148 | screen = fsm.memory[0]
149 | screen.scroll_screen()
150 |
151 | def DoCursorSave (fsm):
152 |
153 | screen = fsm.memory[0]
154 | screen.cursor_save_attrs()
155 |
156 | def DoCursorRestore (fsm):
157 |
158 | screen = fsm.memory[0]
159 | screen.cursor_restore_attrs()
160 |
161 | def DoScrollRegion (fsm):
162 |
163 | screen = fsm.memory[0]
164 | r2 = int(fsm.memory.pop())
165 | r1 = int(fsm.memory.pop())
166 | screen.scroll_screen_rows (r1,r2)
167 |
168 | def DoMode (fsm):
169 |
170 | screen = fsm.memory[0]
171 | mode = fsm.memory.pop() # Should be 4
172 | # screen.setReplaceMode ()
173 |
174 | def DoLog (fsm):
175 |
176 | screen = fsm.memory[0]
177 | fsm.memory = [screen]
178 | fout = open ('log', 'a')
179 | fout.write (fsm.input_symbol + ',' + fsm.current_state + '\n')
180 | fout.close()
181 |
182 | class term (screen.screen):
183 |
184 | '''This class is an abstract, generic terminal.
185 | This does nothing. This is a placeholder that
186 | provides a common base class for other terminals
187 | such as an ANSI terminal. '''
188 |
189 | def __init__ (self, r=24, c=80, *args, **kwargs):
190 |
191 | screen.screen.__init__(self, r,c,*args,**kwargs)
192 |
193 | class ANSI (term):
194 | '''This class implements an ANSI (VT100) terminal.
195 | It is a stream filter that recognizes ANSI terminal
196 | escape sequences and maintains the state of a screen object. '''
197 |
198 | def __init__ (self, r=24,c=80,*args,**kwargs):
199 |
200 | term.__init__(self,r,c,*args,**kwargs)
201 |
202 | #self.screen = screen (24,80)
203 | self.state = FSM.FSM ('INIT',[self])
204 | self.state.set_default_transition (DoLog, 'INIT')
205 | self.state.add_transition_any ('INIT', DoEmit, 'INIT')
206 | self.state.add_transition ('\x1b', 'INIT', None, 'ESC')
207 | self.state.add_transition_any ('ESC', DoLog, 'INIT')
208 | self.state.add_transition ('(', 'ESC', None, 'G0SCS')
209 | self.state.add_transition (')', 'ESC', None, 'G1SCS')
210 | self.state.add_transition_list ('AB012', 'G0SCS', None, 'INIT')
211 | self.state.add_transition_list ('AB012', 'G1SCS', None, 'INIT')
212 | self.state.add_transition ('7', 'ESC', DoCursorSave, 'INIT')
213 | self.state.add_transition ('8', 'ESC', DoCursorRestore, 'INIT')
214 | self.state.add_transition ('M', 'ESC', DoUpReverse, 'INIT')
215 | self.state.add_transition ('>', 'ESC', DoUpReverse, 'INIT')
216 | self.state.add_transition ('<', 'ESC', DoUpReverse, 'INIT')
217 | self.state.add_transition ('=', 'ESC', None, 'INIT') # Selects application keypad.
218 | self.state.add_transition ('#', 'ESC', None, 'GRAPHICS_POUND')
219 | self.state.add_transition_any ('GRAPHICS_POUND', None, 'INIT')
220 | self.state.add_transition ('[', 'ESC', None, 'ELB')
221 | # ELB means Escape Left Bracket. That is ^[[
222 | self.state.add_transition ('H', 'ELB', DoHomeOrigin, 'INIT')
223 | self.state.add_transition ('D', 'ELB', DoBackOne, 'INIT')
224 | self.state.add_transition ('B', 'ELB', DoDownOne, 'INIT')
225 | self.state.add_transition ('C', 'ELB', DoForwardOne, 'INIT')
226 | self.state.add_transition ('A', 'ELB', DoUpOne, 'INIT')
227 | self.state.add_transition ('J', 'ELB', DoEraseDown, 'INIT')
228 | self.state.add_transition ('K', 'ELB', DoEraseEndOfLine, 'INIT')
229 | self.state.add_transition ('r', 'ELB', DoEnableScroll, 'INIT')
230 | self.state.add_transition ('m', 'ELB', self.do_sgr, 'INIT')
231 | self.state.add_transition ('?', 'ELB', None, 'MODECRAP')
232 | self.state.add_transition_list (string.digits, 'ELB', DoStartNumber, 'NUMBER_1')
233 | self.state.add_transition_list (string.digits, 'NUMBER_1', DoBuildNumber, 'NUMBER_1')
234 | self.state.add_transition ('D', 'NUMBER_1', DoBack, 'INIT')
235 | self.state.add_transition ('B', 'NUMBER_1', DoDown, 'INIT')
236 | self.state.add_transition ('C', 'NUMBER_1', DoForward, 'INIT')
237 | self.state.add_transition ('A', 'NUMBER_1', DoUp, 'INIT')
238 | self.state.add_transition ('J', 'NUMBER_1', DoErase, 'INIT')
239 | self.state.add_transition ('K', 'NUMBER_1', DoEraseLine, 'INIT')
240 | self.state.add_transition ('l', 'NUMBER_1', DoMode, 'INIT')
241 | ### It gets worse... the 'm' code can have infinite number of
242 | ### number;number;number before it. I've never seen more than two,
243 | ### but the specs say it's allowed. crap!
244 | self.state.add_transition ('m', 'NUMBER_1', self.do_sgr, 'INIT')
245 | ### LED control. Same implementation problem as 'm' code.
246 | self.state.add_transition ('q', 'NUMBER_1', self.do_decsca, 'INIT')
247 |
248 | # \E[?47h switch to alternate screen
249 | # \E[?47l restores to normal screen from alternate screen.
250 | self.state.add_transition_list (string.digits, 'MODECRAP', DoStartNumber, 'MODECRAP_NUM')
251 | self.state.add_transition_list (string.digits, 'MODECRAP_NUM', DoBuildNumber, 'MODECRAP_NUM')
252 | self.state.add_transition ('l', 'MODECRAP_NUM', self.do_modecrap, 'INIT')
253 | self.state.add_transition ('h', 'MODECRAP_NUM', self.do_modecrap, 'INIT')
254 |
255 | #RM Reset Mode Esc [ Ps l none
256 | self.state.add_transition (';', 'NUMBER_1', None, 'SEMICOLON')
257 | self.state.add_transition_any ('SEMICOLON', DoLog, 'INIT')
258 | self.state.add_transition_list (string.digits, 'SEMICOLON', DoStartNumber, 'NUMBER_2')
259 | self.state.add_transition_list (string.digits, 'NUMBER_2', DoBuildNumber, 'NUMBER_2')
260 | self.state.add_transition_any ('NUMBER_2', DoLog, 'INIT')
261 | self.state.add_transition ('H', 'NUMBER_2', DoHome, 'INIT')
262 | self.state.add_transition ('f', 'NUMBER_2', DoHome, 'INIT')
263 | self.state.add_transition ('r', 'NUMBER_2', DoScrollRegion, 'INIT')
264 | ### It gets worse... the 'm' code can have infinite number of
265 | ### number;number;number before it. I've never seen more than two,
266 | ### but the specs say it's allowed. crap!
267 | self.state.add_transition ('m', 'NUMBER_2', self.do_sgr, 'INIT')
268 | ### LED control. Same problem as 'm' code.
269 | self.state.add_transition ('q', 'NUMBER_2', self.do_decsca, 'INIT')
270 | self.state.add_transition (';', 'NUMBER_2', None, 'SEMICOLON_X')
271 |
272 | # Create a state for 'q' and 'm' which allows an infinite number of ignored numbers
273 | self.state.add_transition_any ('SEMICOLON_X', DoLog, 'INIT')
274 | self.state.add_transition_list (string.digits, 'SEMICOLON_X', DoStartNumber, 'NUMBER_X')
275 | self.state.add_transition_list (string.digits, 'NUMBER_X', DoBuildNumber, 'NUMBER_X')
276 | self.state.add_transition_any ('NUMBER_X', DoLog, 'INIT')
277 | self.state.add_transition ('m', 'NUMBER_X', self.do_sgr, 'INIT')
278 | self.state.add_transition ('q', 'NUMBER_X', self.do_decsca, 'INIT')
279 | self.state.add_transition (';', 'NUMBER_X', None, 'SEMICOLON_X')
280 |
281 | def process (self, c):
282 | """Process a single character. Called by :meth:`write`."""
283 | if isinstance(c, bytes):
284 | c = self._decode(c)
285 | self.state.process(c)
286 |
287 | def process_list (self, l):
288 |
289 | self.write(l)
290 |
291 | def write (self, s):
292 | """Process text, writing it to the virtual screen while handling
293 | ANSI escape codes.
294 | """
295 | if isinstance(s, bytes):
296 | s = self._decode(s)
297 | for c in s:
298 | self.process(c)
299 |
300 | def flush (self):
301 | pass
302 |
303 | def write_ch (self, ch):
304 | '''This puts a character at the current cursor position. The cursor
305 | position is moved forward with wrap-around, but no scrolling is done if
306 | the cursor hits the lower-right corner of the screen. '''
307 |
308 | if isinstance(ch, bytes):
309 | ch = self._decode(ch)
310 |
311 | #\r and \n both produce a call to cr() and lf(), respectively.
312 | ch = ch[0]
313 |
314 | if ch == u'\r':
315 | self.cr()
316 | return
317 | if ch == u'\n':
318 | self.crlf()
319 | return
320 | if ch == chr(screen.BS):
321 | self.cursor_back()
322 | return
323 | self.put_abs(self.cur_r, self.cur_c, ch)
324 | old_r = self.cur_r
325 | old_c = self.cur_c
326 | self.cursor_forward()
327 | if old_c == self.cur_c:
328 | self.cursor_down()
329 | if old_r != self.cur_r:
330 | self.cursor_home (self.cur_r, 1)
331 | else:
332 | self.scroll_up ()
333 | self.cursor_home (self.cur_r, 1)
334 | self.erase_line()
335 |
336 | def do_sgr (self, fsm):
337 | '''Select Graphic Rendition, e.g. color. '''
338 | screen = fsm.memory[0]
339 | fsm.memory = [screen]
340 |
341 | def do_decsca (self, fsm):
342 | '''Select character protection attribute. '''
343 | screen = fsm.memory[0]
344 | fsm.memory = [screen]
345 |
346 | def do_modecrap (self, fsm):
347 | '''Handler for \x1b[?h and \x1b[?l. If anyone
348 | wanted to actually use these, they'd need to add more states to the
349 | FSM rather than just improve or override this method. '''
350 | screen = fsm.memory[0]
351 | fsm.memory = [screen]
352 |
--------------------------------------------------------------------------------
/deps/pexpect/FSM.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | '''This module implements a Finite State Machine (FSM). In addition to state
4 | this FSM also maintains a user defined "memory". So this FSM can be used as a
5 | Push-down Automata (PDA) since a PDA is a FSM + memory.
6 |
7 | The following describes how the FSM works, but you will probably also need to
8 | see the example function to understand how the FSM is used in practice.
9 |
10 | You define an FSM by building tables of transitions. For a given input symbol
11 | the process() method uses these tables to decide what action to call and what
12 | the next state will be. The FSM has a table of transitions that associate:
13 |
14 | (input_symbol, current_state) --> (action, next_state)
15 |
16 | Where "action" is a function you define. The symbols and states can be any
17 | objects. You use the add_transition() and add_transition_list() methods to add
18 | to the transition table. The FSM also has a table of transitions that
19 | associate:
20 |
21 | (current_state) --> (action, next_state)
22 |
23 | You use the add_transition_any() method to add to this transition table. The
24 | FSM also has one default transition that is not associated with any specific
25 | input_symbol or state. You use the set_default_transition() method to set the
26 | default transition.
27 |
28 | When an action function is called it is passed a reference to the FSM. The
29 | action function may then access attributes of the FSM such as input_symbol,
30 | current_state, or "memory". The "memory" attribute can be any object that you
31 | want to pass along to the action functions. It is not used by the FSM itself.
32 | For parsing you would typically pass a list to be used as a stack.
33 |
34 | The processing sequence is as follows. The process() method is given an
35 | input_symbol to process. The FSM will search the table of transitions that
36 | associate:
37 |
38 | (input_symbol, current_state) --> (action, next_state)
39 |
40 | If the pair (input_symbol, current_state) is found then process() will call the
41 | associated action function and then set the current state to the next_state.
42 |
43 | If the FSM cannot find a match for (input_symbol, current_state) it will then
44 | search the table of transitions that associate:
45 |
46 | (current_state) --> (action, next_state)
47 |
48 | If the current_state is found then the process() method will call the
49 | associated action function and then set the current state to the next_state.
50 | Notice that this table lacks an input_symbol. It lets you define transitions
51 | for a current_state and ANY input_symbol. Hence, it is called the "any" table.
52 | Remember, it is always checked after first searching the table for a specific
53 | (input_symbol, current_state).
54 |
55 | For the case where the FSM did not match either of the previous two cases the
56 | FSM will try to use the default transition. If the default transition is
57 | defined then the process() method will call the associated action function and
58 | then set the current state to the next_state. This lets you define a default
59 | transition as a catch-all case. You can think of it as an exception handler.
60 | There can be only one default transition.
61 |
62 | Finally, if none of the previous cases are defined for an input_symbol and
63 | current_state then the FSM will raise an exception. This may be desirable, but
64 | you can always prevent this just by defining a default transition.
65 |
66 | Noah Spurrier 20020822
67 |
68 | PEXPECT LICENSE
69 |
70 | This license is approved by the OSI and FSF as GPL-compatible.
71 | http://opensource.org/licenses/isc-license.txt
72 |
73 | Copyright (c) 2012, Noah Spurrier
74 | PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
75 | PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
76 | COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
77 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
78 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
79 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
80 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
81 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
82 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
83 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
84 |
85 | '''
86 |
87 | class ExceptionFSM(Exception):
88 |
89 | '''This is the FSM Exception class.'''
90 |
91 | def __init__(self, value):
92 | self.value = value
93 |
94 | def __str__(self):
95 | return 'ExceptionFSM: ' + str(self.value)
96 |
97 | class FSM:
98 |
99 | '''This is a Finite State Machine (FSM).
100 | '''
101 |
102 | def __init__(self, initial_state, memory=None):
103 |
104 | '''This creates the FSM. You set the initial state here. The "memory"
105 | attribute is any object that you want to pass along to the action
106 | functions. It is not used by the FSM. For parsing you would typically
107 | pass a list to be used as a stack. '''
108 |
109 | # Map (input_symbol, current_state) --> (action, next_state).
110 | self.state_transitions = {}
111 | # Map (current_state) --> (action, next_state).
112 | self.state_transitions_any = {}
113 | self.default_transition = None
114 |
115 | self.input_symbol = None
116 | self.initial_state = initial_state
117 | self.current_state = self.initial_state
118 | self.next_state = None
119 | self.action = None
120 | self.memory = memory
121 |
122 | def reset (self):
123 |
124 | '''This sets the current_state to the initial_state and sets
125 | input_symbol to None. The initial state was set by the constructor
126 | __init__(). '''
127 |
128 | self.current_state = self.initial_state
129 | self.input_symbol = None
130 |
131 | def add_transition (self, input_symbol, state, action=None, next_state=None):
132 |
133 | '''This adds a transition that associates:
134 |
135 | (input_symbol, current_state) --> (action, next_state)
136 |
137 | The action may be set to None in which case the process() method will
138 | ignore the action and only set the next_state. The next_state may be
139 | set to None in which case the current state will be unchanged.
140 |
141 | You can also set transitions for a list of symbols by using
142 | add_transition_list(). '''
143 |
144 | if next_state is None:
145 | next_state = state
146 | self.state_transitions[(input_symbol, state)] = (action, next_state)
147 |
148 | def add_transition_list (self, list_input_symbols, state, action=None, next_state=None):
149 |
150 | '''This adds the same transition for a list of input symbols.
151 | You can pass a list or a string. Note that it is handy to use
152 | string.digits, string.whitespace, string.letters, etc. to add
153 | transitions that match character classes.
154 |
155 | The action may be set to None in which case the process() method will
156 | ignore the action and only set the next_state. The next_state may be
157 | set to None in which case the current state will be unchanged. '''
158 |
159 | if next_state is None:
160 | next_state = state
161 | for input_symbol in list_input_symbols:
162 | self.add_transition (input_symbol, state, action, next_state)
163 |
164 | def add_transition_any (self, state, action=None, next_state=None):
165 |
166 | '''This adds a transition that associates:
167 |
168 | (current_state) --> (action, next_state)
169 |
170 | That is, any input symbol will match the current state.
171 | The process() method checks the "any" state associations after it first
172 | checks for an exact match of (input_symbol, current_state).
173 |
174 | The action may be set to None in which case the process() method will
175 | ignore the action and only set the next_state. The next_state may be
176 | set to None in which case the current state will be unchanged. '''
177 |
178 | if next_state is None:
179 | next_state = state
180 | self.state_transitions_any [state] = (action, next_state)
181 |
182 | def set_default_transition (self, action, next_state):
183 |
184 | '''This sets the default transition. This defines an action and
185 | next_state if the FSM cannot find the input symbol and the current
186 | state in the transition list and if the FSM cannot find the
187 | current_state in the transition_any list. This is useful as a final
188 | fall-through state for catching errors and undefined states.
189 |
190 | The default transition can be removed by setting the attribute
191 | default_transition to None. '''
192 |
193 | self.default_transition = (action, next_state)
194 |
195 | def get_transition (self, input_symbol, state):
196 |
197 | '''This returns (action, next state) given an input_symbol and state.
198 | This does not modify the FSM state, so calling this method has no side
199 | effects. Normally you do not call this method directly. It is called by
200 | process().
201 |
202 | The sequence of steps to check for a defined transition goes from the
203 | most specific to the least specific.
204 |
205 | 1. Check state_transitions[] that match exactly the tuple,
206 | (input_symbol, state)
207 |
208 | 2. Check state_transitions_any[] that match (state)
209 | In other words, match a specific state and ANY input_symbol.
210 |
211 | 3. Check if the default_transition is defined.
212 | This catches any input_symbol and any state.
213 | This is a handler for errors, undefined states, or defaults.
214 |
215 | 4. No transition was defined. If we get here then raise an exception.
216 | '''
217 |
218 | if (input_symbol, state) in self.state_transitions:
219 | return self.state_transitions[(input_symbol, state)]
220 | elif state in self.state_transitions_any:
221 | return self.state_transitions_any[state]
222 | elif self.default_transition is not None:
223 | return self.default_transition
224 | else:
225 | raise ExceptionFSM ('Transition is undefined: (%s, %s).' %
226 | (str(input_symbol), str(state)) )
227 |
228 | def process (self, input_symbol):
229 |
230 | '''This is the main method that you call to process input. This may
231 | cause the FSM to change state and call an action. This method calls
232 | get_transition() to find the action and next_state associated with the
233 | input_symbol and current_state. If the action is None then the action
234 | is not called and only the current state is changed. This method
235 | processes one complete input symbol. You can process a list of symbols
236 | (or a string) by calling process_list(). '''
237 |
238 | self.input_symbol = input_symbol
239 | (self.action, self.next_state) = self.get_transition (self.input_symbol, self.current_state)
240 | if self.action is not None:
241 | self.action (self)
242 | self.current_state = self.next_state
243 | self.next_state = None
244 |
245 | def process_list (self, input_symbols):
246 |
247 | '''This takes a list and sends each element to process(). The list may
248 | be a string or any iterable object. '''
249 |
250 | for s in input_symbols:
251 | self.process (s)
252 |
253 | ##############################################################################
254 | # The following is an example that demonstrates the use of the FSM class to
255 | # process an RPN expression. Run this module from the command line. You will
256 | # get a prompt > for input. Enter an RPN Expression. Numbers may be integers.
257 | # Operators are * / + - Use the = sign to evaluate and print the expression.
258 | # For example:
259 | #
260 | # 167 3 2 2 * * * 1 - =
261 | #
262 | # will print:
263 | #
264 | # 2003
265 | ##############################################################################
266 |
267 | import sys
268 | import string
269 |
270 | PY3 = (sys.version_info[0] >= 3)
271 |
272 | #
273 | # These define the actions.
274 | # Note that "memory" is a list being used as a stack.
275 | #
276 |
277 | def BeginBuildNumber (fsm):
278 | fsm.memory.append (fsm.input_symbol)
279 |
280 | def BuildNumber (fsm):
281 | s = fsm.memory.pop ()
282 | s = s + fsm.input_symbol
283 | fsm.memory.append (s)
284 |
285 | def EndBuildNumber (fsm):
286 | s = fsm.memory.pop ()
287 | fsm.memory.append (int(s))
288 |
289 | def DoOperator (fsm):
290 | ar = fsm.memory.pop()
291 | al = fsm.memory.pop()
292 | if fsm.input_symbol == '+':
293 | fsm.memory.append (al + ar)
294 | elif fsm.input_symbol == '-':
295 | fsm.memory.append (al - ar)
296 | elif fsm.input_symbol == '*':
297 | fsm.memory.append (al * ar)
298 | elif fsm.input_symbol == '/':
299 | fsm.memory.append (al / ar)
300 |
301 | def DoEqual (fsm):
302 | print(str(fsm.memory.pop()))
303 |
304 | def Error (fsm):
305 | print('That does not compute.')
306 | print(str(fsm.input_symbol))
307 |
308 | def main():
309 |
310 | '''This is where the example starts and the FSM state transitions are
311 | defined. Note that states are strings (such as 'INIT'). This is not
312 | necessary, but it makes the example easier to read. '''
313 |
314 | f = FSM ('INIT', [])
315 | f.set_default_transition (Error, 'INIT')
316 | f.add_transition_any ('INIT', None, 'INIT')
317 | f.add_transition ('=', 'INIT', DoEqual, 'INIT')
318 | f.add_transition_list (string.digits, 'INIT', BeginBuildNumber, 'BUILDING_NUMBER')
319 | f.add_transition_list (string.digits, 'BUILDING_NUMBER', BuildNumber, 'BUILDING_NUMBER')
320 | f.add_transition_list (string.whitespace, 'BUILDING_NUMBER', EndBuildNumber, 'INIT')
321 | f.add_transition_list ('+-*/', 'INIT', DoOperator, 'INIT')
322 |
323 | print()
324 | print('Enter an RPN Expression.')
325 | print('Numbers may be integers. Operators are * / + -')
326 | print('Use the = sign to evaluate and print the expression.')
327 | print('For example: ')
328 | print(' 167 3 2 2 * * * 1 - =')
329 | inputstr = (input if PY3 else raw_input)('> ') # analysis:ignore
330 | f.process_list(inputstr)
331 |
332 |
333 | if __name__ == '__main__':
334 | main()
335 |
--------------------------------------------------------------------------------
/deps/pexpect/__init__.py:
--------------------------------------------------------------------------------
1 | '''Pexpect is a Python module for spawning child applications and controlling
2 | them automatically. Pexpect can be used for automating interactive applications
3 | such as ssh, ftp, passwd, telnet, etc. It can be used to a automate setup
4 | scripts for duplicating software package installations on different servers. It
5 | can be used for automated software testing. Pexpect is in the spirit of Don
6 | Libes' Expect, but Pexpect is pure Python. Other Expect-like modules for Python
7 | require TCL and Expect or require C extensions to be compiled. Pexpect does not
8 | use C, Expect, or TCL extensions. It should work on any platform that supports
9 | the standard Python pty module. The Pexpect interface focuses on ease of use so
10 | that simple tasks are easy.
11 |
12 | There are two main interfaces to the Pexpect system; these are the function,
13 | run() and the class, spawn. The spawn class is more powerful. The run()
14 | function is simpler than spawn, and is good for quickly calling program. When
15 | you call the run() function it executes a given program and then returns the
16 | output. This is a handy replacement for os.system().
17 |
18 | For example::
19 |
20 | pexpect.run('ls -la')
21 |
22 | The spawn class is the more powerful interface to the Pexpect system. You can
23 | use this to spawn a child program then interact with it by sending input and
24 | expecting responses (waiting for patterns in the child's output).
25 |
26 | For example::
27 |
28 | child = pexpect.spawn('scp foo user@example.com:.')
29 | child.expect('Password:')
30 | child.sendline(mypassword)
31 |
32 | This works even for commands that ask for passwords or other input outside of
33 | the normal stdio streams. For example, ssh reads input directly from the TTY
34 | device which bypasses stdin.
35 |
36 | Credits: Noah Spurrier, Richard Holden, Marco Molteni, Kimberley Burchett,
37 | Robert Stone, Hartmut Goebel, Chad Schroeder, Erick Tryzelaar, Dave Kirby, Ids
38 | vander Molen, George Todd, Noel Taylor, Nicolas D. Cesar, Alexander Gattin,
39 | Jacques-Etienne Baudoux, Geoffrey Marshall, Francisco Lourenco, Glen Mabey,
40 | Karthik Gurusamy, Fernando Perez, Corey Minyard, Jon Cohen, Guillaume
41 | Chazarain, Andrew Ryan, Nick Craig-Wood, Andrew Stone, Jorgen Grahn, John
42 | Spiegel, Jan Grant, and Shane Kerr. Let me know if I forgot anyone.
43 |
44 | Pexpect is free, open source, and all that good stuff.
45 | http://pexpect.sourceforge.net/
46 |
47 | PEXPECT LICENSE
48 |
49 | This license is approved by the OSI and FSF as GPL-compatible.
50 | http://opensource.org/licenses/isc-license.txt
51 |
52 | Copyright (c) 2012, Noah Spurrier
53 | PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
54 | PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
55 | COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
56 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
57 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
58 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
59 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
60 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
61 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
62 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
63 |
64 | '''
65 |
66 | import sys
67 | PY3 = (sys.version_info[0] >= 3)
68 |
69 | from .exceptions import ExceptionPexpect, EOF, TIMEOUT
70 | from .utils import split_command_line, which, is_executable_file
71 | from .expect import Expecter, searcher_re, searcher_string
72 |
73 | if sys.platform != 'win32':
74 | # On Unix, these are available at the top level for backwards compatibility
75 | from .pty_spawn import spawn, spawnu
76 | from .run import run, runu
77 |
78 | __version__ = '4.8.0'
79 | __revision__ = ''
80 | __all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'spawnu', 'run', 'runu',
81 | 'which', 'split_command_line', '__version__', '__revision__']
82 |
83 |
84 |
85 | # vim: set shiftround expandtab tabstop=4 shiftwidth=4 ft=python autoindent :
86 |
--------------------------------------------------------------------------------
/deps/pexpect/_async.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import errno
3 | import signal
4 |
5 | from pexpect import EOF
6 |
7 | @asyncio.coroutine
8 | def expect_async(expecter, timeout=None):
9 | # First process data that was previously read - if it maches, we don't need
10 | # async stuff.
11 | idx = expecter.existing_data()
12 | if idx is not None:
13 | return idx
14 | if not expecter.spawn.async_pw_transport:
15 | pw = PatternWaiter()
16 | pw.set_expecter(expecter)
17 | transport, pw = yield from asyncio.get_event_loop()\
18 | .connect_read_pipe(lambda: pw, expecter.spawn)
19 | expecter.spawn.async_pw_transport = pw, transport
20 | else:
21 | pw, transport = expecter.spawn.async_pw_transport
22 | pw.set_expecter(expecter)
23 | transport.resume_reading()
24 | try:
25 | return (yield from asyncio.wait_for(pw.fut, timeout))
26 | except asyncio.TimeoutError as e:
27 | transport.pause_reading()
28 | return expecter.timeout(e)
29 |
30 | @asyncio.coroutine
31 | def repl_run_command_async(repl, cmdlines, timeout=-1):
32 | res = []
33 | repl.child.sendline(cmdlines[0])
34 | for line in cmdlines[1:]:
35 | yield from repl._expect_prompt(timeout=timeout, async_=True)
36 | res.append(repl.child.before)
37 | repl.child.sendline(line)
38 |
39 | # Command was fully submitted, now wait for the next prompt
40 | prompt_idx = yield from repl._expect_prompt(timeout=timeout, async_=True)
41 | if prompt_idx == 1:
42 | # We got the continuation prompt - command was incomplete
43 | repl.child.kill(signal.SIGINT)
44 | yield from repl._expect_prompt(timeout=1, async_=True)
45 | raise ValueError("Continuation prompt found - input was incomplete:")
46 | return u''.join(res + [repl.child.before])
47 |
48 | class PatternWaiter(asyncio.Protocol):
49 | transport = None
50 |
51 | def set_expecter(self, expecter):
52 | self.expecter = expecter
53 | self.fut = asyncio.Future()
54 |
55 | def found(self, result):
56 | if not self.fut.done():
57 | self.fut.set_result(result)
58 | self.transport.pause_reading()
59 |
60 | def error(self, exc):
61 | if not self.fut.done():
62 | self.fut.set_exception(exc)
63 | self.transport.pause_reading()
64 |
65 | def connection_made(self, transport):
66 | self.transport = transport
67 |
68 | def data_received(self, data):
69 | spawn = self.expecter.spawn
70 | s = spawn._decoder.decode(data)
71 | spawn._log(s, 'read')
72 |
73 | if self.fut.done():
74 | spawn._before.write(s)
75 | spawn._buffer.write(s)
76 | return
77 |
78 | try:
79 | index = self.expecter.new_data(s)
80 | if index is not None:
81 | # Found a match
82 | self.found(index)
83 | except Exception as e:
84 | self.expecter.errored()
85 | self.error(e)
86 |
87 | def eof_received(self):
88 | # N.B. If this gets called, async will close the pipe (the spawn object)
89 | # for us
90 | try:
91 | self.expecter.spawn.flag_eof = True
92 | index = self.expecter.eof()
93 | except EOF as e:
94 | self.error(e)
95 | else:
96 | self.found(index)
97 |
98 | def connection_lost(self, exc):
99 | if isinstance(exc, OSError) and exc.errno == errno.EIO:
100 | # We may get here without eof_received being called, e.g on Linux
101 | self.eof_received()
102 | elif exc is not None:
103 | self.error(exc)
104 |
--------------------------------------------------------------------------------
/deps/pexpect/bashrc.sh:
--------------------------------------------------------------------------------
1 | # Different platforms have different names for the systemwide bashrc
2 | if [[ -f /etc/bashrc ]]; then
3 | source /etc/bashrc
4 | fi
5 | if [[ -f /etc/bash.bashrc ]]; then
6 | source /etc/bash.bashrc
7 | fi
8 | if [[ -f ~/.bashrc ]]; then
9 | source ~/.bashrc
10 | fi
11 |
12 | # Reset PS1 so pexpect can find it
13 | PS1="$"
14 |
15 | # Unset PROMPT_COMMAND, so that it can't change PS1 to something unexpected.
16 | unset PROMPT_COMMAND
17 |
--------------------------------------------------------------------------------
/deps/pexpect/exceptions.py:
--------------------------------------------------------------------------------
1 | """Exception classes used by Pexpect"""
2 |
3 | import traceback
4 | import sys
5 |
6 | class ExceptionPexpect(Exception):
7 | '''Base class for all exceptions raised by this module.
8 | '''
9 |
10 | def __init__(self, value):
11 | super(ExceptionPexpect, self).__init__(value)
12 | self.value = value
13 |
14 | def __str__(self):
15 | return str(self.value)
16 |
17 | def get_trace(self):
18 | '''This returns an abbreviated stack trace with lines that only concern
19 | the caller. In other words, the stack trace inside the Pexpect module
20 | is not included. '''
21 |
22 | tblist = traceback.extract_tb(sys.exc_info()[2])
23 | tblist = [item for item in tblist if ('pexpect/__init__' not in item[0])
24 | and ('pexpect/expect' not in item[0])]
25 | tblist = traceback.format_list(tblist)
26 | return ''.join(tblist)
27 |
28 |
29 | class EOF(ExceptionPexpect):
30 | '''Raised when EOF is read from a child.
31 | This usually means the child has exited.'''
32 |
33 |
34 | class TIMEOUT(ExceptionPexpect):
35 | '''Raised when a read time exceeds the timeout. '''
36 |
--------------------------------------------------------------------------------
/deps/pexpect/expect.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 | from .exceptions import EOF, TIMEOUT
4 |
5 | class Expecter(object):
6 | def __init__(self, spawn, searcher, searchwindowsize=-1):
7 | self.spawn = spawn
8 | self.searcher = searcher
9 | # A value of -1 means to use the figure from spawn, which should
10 | # be None or a positive number.
11 | if searchwindowsize == -1:
12 | searchwindowsize = spawn.searchwindowsize
13 | self.searchwindowsize = searchwindowsize
14 | self.lookback = None
15 | if hasattr(searcher, 'longest_string'):
16 | self.lookback = searcher.longest_string
17 |
18 | def do_search(self, window, freshlen):
19 | spawn = self.spawn
20 | searcher = self.searcher
21 | if freshlen > len(window):
22 | freshlen = len(window)
23 | index = searcher.search(window, freshlen, self.searchwindowsize)
24 | if index >= 0:
25 | spawn._buffer = spawn.buffer_type()
26 | spawn._buffer.write(window[searcher.end:])
27 | spawn.before = spawn._before.getvalue()[
28 | 0:-(len(window) - searcher.start)]
29 | spawn._before = spawn.buffer_type()
30 | spawn._before.write(window[searcher.end:])
31 | spawn.after = window[searcher.start:searcher.end]
32 | spawn.match = searcher.match
33 | spawn.match_index = index
34 | # Found a match
35 | return index
36 | elif self.searchwindowsize or self.lookback:
37 | maintain = self.searchwindowsize or self.lookback
38 | if spawn._buffer.tell() > maintain:
39 | spawn._buffer = spawn.buffer_type()
40 | spawn._buffer.write(window[-maintain:])
41 |
42 | def existing_data(self):
43 | # First call from a new call to expect_loop or expect_async.
44 | # self.searchwindowsize may have changed.
45 | # Treat all data as fresh.
46 | spawn = self.spawn
47 | before_len = spawn._before.tell()
48 | buf_len = spawn._buffer.tell()
49 | freshlen = before_len
50 | if before_len > buf_len:
51 | if not self.searchwindowsize:
52 | spawn._buffer = spawn.buffer_type()
53 | window = spawn._before.getvalue()
54 | spawn._buffer.write(window)
55 | elif buf_len < self.searchwindowsize:
56 | spawn._buffer = spawn.buffer_type()
57 | spawn._before.seek(
58 | max(0, before_len - self.searchwindowsize))
59 | window = spawn._before.read()
60 | spawn._buffer.write(window)
61 | else:
62 | spawn._buffer.seek(max(0, buf_len - self.searchwindowsize))
63 | window = spawn._buffer.read()
64 | else:
65 | if self.searchwindowsize:
66 | spawn._buffer.seek(max(0, buf_len - self.searchwindowsize))
67 | window = spawn._buffer.read()
68 | else:
69 | window = spawn._buffer.getvalue()
70 | return self.do_search(window, freshlen)
71 |
72 | def new_data(self, data):
73 | # A subsequent call, after a call to existing_data.
74 | spawn = self.spawn
75 | freshlen = len(data)
76 | spawn._before.write(data)
77 | if not self.searchwindowsize:
78 | if self.lookback:
79 | # search lookback + new data.
80 | old_len = spawn._buffer.tell()
81 | spawn._buffer.write(data)
82 | spawn._buffer.seek(max(0, old_len - self.lookback))
83 | window = spawn._buffer.read()
84 | else:
85 | # copy the whole buffer (really slow for large datasets).
86 | spawn._buffer.write(data)
87 | window = spawn.buffer
88 | else:
89 | if len(data) >= self.searchwindowsize or not spawn._buffer.tell():
90 | window = data[-self.searchwindowsize:]
91 | spawn._buffer = spawn.buffer_type()
92 | spawn._buffer.write(window[-self.searchwindowsize:])
93 | else:
94 | spawn._buffer.write(data)
95 | new_len = spawn._buffer.tell()
96 | spawn._buffer.seek(max(0, new_len - self.searchwindowsize))
97 | window = spawn._buffer.read()
98 | return self.do_search(window, freshlen)
99 |
100 | def eof(self, err=None):
101 | spawn = self.spawn
102 |
103 | spawn.before = spawn._before.getvalue()
104 | spawn._buffer = spawn.buffer_type()
105 | spawn._before = spawn.buffer_type()
106 | spawn.after = EOF
107 | index = self.searcher.eof_index
108 | if index >= 0:
109 | spawn.match = EOF
110 | spawn.match_index = index
111 | return index
112 | else:
113 | spawn.match = None
114 | spawn.match_index = None
115 | msg = str(spawn)
116 | msg += '\nsearcher: %s' % self.searcher
117 | if err is not None:
118 | msg = str(err) + '\n' + msg
119 |
120 | exc = EOF(msg)
121 | exc.__cause__ = None # in Python 3.x we can use "raise exc from None"
122 | raise exc
123 |
124 | def timeout(self, err=None):
125 | spawn = self.spawn
126 |
127 | spawn.before = spawn._before.getvalue()
128 | spawn.after = TIMEOUT
129 | index = self.searcher.timeout_index
130 | if index >= 0:
131 | spawn.match = TIMEOUT
132 | spawn.match_index = index
133 | return index
134 | else:
135 | spawn.match = None
136 | spawn.match_index = None
137 | msg = str(spawn)
138 | msg += '\nsearcher: %s' % self.searcher
139 | if err is not None:
140 | msg = str(err) + '\n' + msg
141 |
142 | exc = TIMEOUT(msg)
143 | exc.__cause__ = None # in Python 3.x we can use "raise exc from None"
144 | raise exc
145 |
146 | def errored(self):
147 | spawn = self.spawn
148 | spawn.before = spawn._before.getvalue()
149 | spawn.after = None
150 | spawn.match = None
151 | spawn.match_index = None
152 |
153 | def expect_loop(self, timeout=-1):
154 | """Blocking expect"""
155 | spawn = self.spawn
156 |
157 | if timeout is not None:
158 | end_time = time.time() + timeout
159 |
160 | try:
161 | idx = self.existing_data()
162 | if idx is not None:
163 | return idx
164 | while True:
165 | # No match at this point
166 | if (timeout is not None) and (timeout < 0):
167 | return self.timeout()
168 | # Still have time left, so read more data
169 | incoming = spawn.read_nonblocking(spawn.maxread, timeout)
170 | if self.spawn.delayafterread is not None:
171 | time.sleep(self.spawn.delayafterread)
172 | idx = self.new_data(incoming)
173 | # Keep reading until exception or return.
174 | if idx is not None:
175 | return idx
176 | if timeout is not None:
177 | timeout = end_time - time.time()
178 | except EOF as e:
179 | return self.eof(e)
180 | except TIMEOUT as e:
181 | return self.timeout(e)
182 | except:
183 | self.errored()
184 | raise
185 |
186 |
187 | class searcher_string(object):
188 | '''This is a plain string search helper for the spawn.expect_any() method.
189 | This helper class is for speed. For more powerful regex patterns
190 | see the helper class, searcher_re.
191 |
192 | Attributes:
193 |
194 | eof_index - index of EOF, or -1
195 | timeout_index - index of TIMEOUT, or -1
196 |
197 | After a successful match by the search() method the following attributes
198 | are available:
199 |
200 | start - index into the buffer, first byte of match
201 | end - index into the buffer, first byte after match
202 | match - the matching string itself
203 |
204 | '''
205 |
206 | def __init__(self, strings):
207 | '''This creates an instance of searcher_string. This argument 'strings'
208 | may be a list; a sequence of strings; or the EOF or TIMEOUT types. '''
209 |
210 | self.eof_index = -1
211 | self.timeout_index = -1
212 | self._strings = []
213 | self.longest_string = 0
214 | for n, s in enumerate(strings):
215 | if s is EOF:
216 | self.eof_index = n
217 | continue
218 | if s is TIMEOUT:
219 | self.timeout_index = n
220 | continue
221 | self._strings.append((n, s))
222 | if len(s) > self.longest_string:
223 | self.longest_string = len(s)
224 |
225 | def __str__(self):
226 | '''This returns a human-readable string that represents the state of
227 | the object.'''
228 |
229 | ss = [(ns[0], ' %d: %r' % ns) for ns in self._strings]
230 | ss.append((-1, 'searcher_string:'))
231 | if self.eof_index >= 0:
232 | ss.append((self.eof_index, ' %d: EOF' % self.eof_index))
233 | if self.timeout_index >= 0:
234 | ss.append((self.timeout_index,
235 | ' %d: TIMEOUT' % self.timeout_index))
236 | ss.sort()
237 | ss = list(zip(*ss))[1]
238 | return '\n'.join(ss)
239 |
240 | def search(self, buffer, freshlen, searchwindowsize=None):
241 | '''This searches 'buffer' for the first occurrence of one of the search
242 | strings. 'freshlen' must indicate the number of bytes at the end of
243 | 'buffer' which have not been searched before. It helps to avoid
244 | searching the same, possibly big, buffer over and over again.
245 |
246 | See class spawn for the 'searchwindowsize' argument.
247 |
248 | If there is a match this returns the index of that string, and sets
249 | 'start', 'end' and 'match'. Otherwise, this returns -1. '''
250 |
251 | first_match = None
252 |
253 | # 'freshlen' helps a lot here. Further optimizations could
254 | # possibly include:
255 | #
256 | # using something like the Boyer-Moore Fast String Searching
257 | # Algorithm; pre-compiling the search through a list of
258 | # strings into something that can scan the input once to
259 | # search for all N strings; realize that if we search for
260 | # ['bar', 'baz'] and the input is '...foo' we need not bother
261 | # rescanning until we've read three more bytes.
262 | #
263 | # Sadly, I don't know enough about this interesting topic. /grahn
264 |
265 | for index, s in self._strings:
266 | if searchwindowsize is None:
267 | # the match, if any, can only be in the fresh data,
268 | # or at the very end of the old data
269 | offset = -(freshlen + len(s))
270 | else:
271 | # better obey searchwindowsize
272 | offset = -searchwindowsize
273 | n = buffer.find(s, offset)
274 | if n >= 0 and (first_match is None or n < first_match):
275 | first_match = n
276 | best_index, best_match = index, s
277 | if first_match is None:
278 | return -1
279 | self.match = best_match
280 | self.start = first_match
281 | self.end = self.start + len(self.match)
282 | return best_index
283 |
284 |
285 | class searcher_re(object):
286 | '''This is regular expression string search helper for the
287 | spawn.expect_any() method. This helper class is for powerful
288 | pattern matching. For speed, see the helper class, searcher_string.
289 |
290 | Attributes:
291 |
292 | eof_index - index of EOF, or -1
293 | timeout_index - index of TIMEOUT, or -1
294 |
295 | After a successful match by the search() method the following attributes
296 | are available:
297 |
298 | start - index into the buffer, first byte of match
299 | end - index into the buffer, first byte after match
300 | match - the re.match object returned by a successful re.search
301 |
302 | '''
303 |
304 | def __init__(self, patterns):
305 | '''This creates an instance that searches for 'patterns' Where
306 | 'patterns' may be a list or other sequence of compiled regular
307 | expressions, or the EOF or TIMEOUT types.'''
308 |
309 | self.eof_index = -1
310 | self.timeout_index = -1
311 | self._searches = []
312 | for n, s in enumerate(patterns):
313 | if s is EOF:
314 | self.eof_index = n
315 | continue
316 | if s is TIMEOUT:
317 | self.timeout_index = n
318 | continue
319 | self._searches.append((n, s))
320 |
321 | def __str__(self):
322 | '''This returns a human-readable string that represents the state of
323 | the object.'''
324 |
325 | #ss = [(n, ' %d: re.compile("%s")' %
326 | # (n, repr(s.pattern))) for n, s in self._searches]
327 | ss = list()
328 | for n, s in self._searches:
329 | ss.append((n, ' %d: re.compile(%r)' % (n, s.pattern)))
330 | ss.append((-1, 'searcher_re:'))
331 | if self.eof_index >= 0:
332 | ss.append((self.eof_index, ' %d: EOF' % self.eof_index))
333 | if self.timeout_index >= 0:
334 | ss.append((self.timeout_index, ' %d: TIMEOUT' %
335 | self.timeout_index))
336 | ss.sort()
337 | ss = list(zip(*ss))[1]
338 | return '\n'.join(ss)
339 |
340 | def search(self, buffer, freshlen, searchwindowsize=None):
341 | '''This searches 'buffer' for the first occurrence of one of the regular
342 | expressions. 'freshlen' must indicate the number of bytes at the end of
343 | 'buffer' which have not been searched before.
344 |
345 | See class spawn for the 'searchwindowsize' argument.
346 |
347 | If there is a match this returns the index of that string, and sets
348 | 'start', 'end' and 'match'. Otherwise, returns -1.'''
349 |
350 | first_match = None
351 | # 'freshlen' doesn't help here -- we cannot predict the
352 | # length of a match, and the re module provides no help.
353 | if searchwindowsize is None:
354 | searchstart = 0
355 | else:
356 | searchstart = max(0, len(buffer) - searchwindowsize)
357 | for index, s in self._searches:
358 | match = s.search(buffer, searchstart)
359 | if match is None:
360 | continue
361 | n = match.start()
362 | if first_match is None or n < first_match:
363 | first_match = n
364 | the_match = match
365 | best_index = index
366 | if first_match is None:
367 | return -1
368 | self.start = first_match
369 | self.match = the_match
370 | self.end = self.match.end()
371 | return best_index
372 |
--------------------------------------------------------------------------------
/deps/pexpect/fdpexpect.py:
--------------------------------------------------------------------------------
1 | '''This is like pexpect, but it will work with any file descriptor that you
2 | pass it. You are responsible for opening and close the file descriptor.
3 | This allows you to use Pexpect with sockets and named pipes (FIFOs).
4 |
5 | PEXPECT LICENSE
6 |
7 | This license is approved by the OSI and FSF as GPL-compatible.
8 | http://opensource.org/licenses/isc-license.txt
9 |
10 | Copyright (c) 2012, Noah Spurrier
11 | PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
12 | PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
13 | COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
14 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 |
22 | '''
23 |
24 | from .spawnbase import SpawnBase
25 | from .exceptions import ExceptionPexpect, TIMEOUT
26 | from .utils import select_ignore_interrupts, poll_ignore_interrupts
27 | import os
28 |
29 | __all__ = ['fdspawn']
30 |
31 | class fdspawn(SpawnBase):
32 | '''This is like pexpect.spawn but allows you to supply your own open file
33 | descriptor. For example, you could use it to read through a file looking
34 | for patterns, or to control a modem or serial device. '''
35 |
36 | def __init__ (self, fd, args=None, timeout=30, maxread=2000, searchwindowsize=None,
37 | logfile=None, encoding=None, codec_errors='strict', use_poll=False):
38 | '''This takes a file descriptor (an int) or an object that support the
39 | fileno() method (returning an int). All Python file-like objects
40 | support fileno(). '''
41 |
42 | if type(fd) != type(0) and hasattr(fd, 'fileno'):
43 | fd = fd.fileno()
44 |
45 | if type(fd) != type(0):
46 | raise ExceptionPexpect('The fd argument is not an int. If this is a command string then maybe you want to use pexpect.spawn.')
47 |
48 | try: # make sure fd is a valid file descriptor
49 | os.fstat(fd)
50 | except OSError:
51 | raise ExceptionPexpect('The fd argument is not a valid file descriptor.')
52 |
53 | self.args = None
54 | self.command = None
55 | SpawnBase.__init__(self, timeout, maxread, searchwindowsize, logfile,
56 | encoding=encoding, codec_errors=codec_errors)
57 | self.child_fd = fd
58 | self.own_fd = False
59 | self.closed = False
60 | self.name = '' % fd
61 | self.use_poll = use_poll
62 |
63 | def close (self):
64 | """Close the file descriptor.
65 |
66 | Calling this method a second time does nothing, but if the file
67 | descriptor was closed elsewhere, :class:`OSError` will be raised.
68 | """
69 | if self.child_fd == -1:
70 | return
71 |
72 | self.flush()
73 | os.close(self.child_fd)
74 | self.child_fd = -1
75 | self.closed = True
76 |
77 | def isalive (self):
78 | '''This checks if the file descriptor is still valid. If :func:`os.fstat`
79 | does not raise an exception then we assume it is alive. '''
80 |
81 | if self.child_fd == -1:
82 | return False
83 | try:
84 | os.fstat(self.child_fd)
85 | return True
86 | except:
87 | return False
88 |
89 | def terminate (self, force=False): # pragma: no cover
90 | '''Deprecated and invalid. Just raises an exception.'''
91 | raise ExceptionPexpect('This method is not valid for file descriptors.')
92 |
93 | # These four methods are left around for backwards compatibility, but not
94 | # documented as part of fdpexpect. You're encouraged to use os.write
95 | # directly.
96 | def send(self, s):
97 | "Write to fd, return number of bytes written"
98 | s = self._coerce_send_string(s)
99 | self._log(s, 'send')
100 |
101 | b = self._encoder.encode(s, final=False)
102 | return os.write(self.child_fd, b)
103 |
104 | def sendline(self, s):
105 | "Write to fd with trailing newline, return number of bytes written"
106 | s = self._coerce_send_string(s)
107 | return self.send(s + self.linesep)
108 |
109 | def write(self, s):
110 | "Write to fd, return None"
111 | self.send(s)
112 |
113 | def writelines(self, sequence):
114 | "Call self.write() for each item in sequence"
115 | for s in sequence:
116 | self.write(s)
117 |
118 | def read_nonblocking(self, size=1, timeout=-1):
119 | """
120 | Read from the file descriptor and return the result as a string.
121 |
122 | The read_nonblocking method of :class:`SpawnBase` assumes that a call
123 | to os.read will not block (timeout parameter is ignored). This is not
124 | the case for POSIX file-like objects such as sockets and serial ports.
125 |
126 | Use :func:`select.select`, timeout is implemented conditionally for
127 | POSIX systems.
128 |
129 | :param int size: Read at most *size* bytes.
130 | :param int timeout: Wait timeout seconds for file descriptor to be
131 | ready to read. When -1 (default), use self.timeout. When 0, poll.
132 | :return: String containing the bytes read
133 | """
134 | if os.name == 'posix':
135 | if timeout == -1:
136 | timeout = self.timeout
137 | rlist = [self.child_fd]
138 | wlist = []
139 | xlist = []
140 | if self.use_poll:
141 | rlist = poll_ignore_interrupts(rlist, timeout)
142 | else:
143 | rlist, wlist, xlist = select_ignore_interrupts(
144 | rlist, wlist, xlist, timeout
145 | )
146 | if self.child_fd not in rlist:
147 | raise TIMEOUT('Timeout exceeded.')
148 | return super(fdspawn, self).read_nonblocking(size)
149 |
--------------------------------------------------------------------------------
/deps/pexpect/popen_spawn.py:
--------------------------------------------------------------------------------
1 | """Provides an interface like pexpect.spawn interface using subprocess.Popen
2 | """
3 | import os
4 | import threading
5 | import subprocess
6 | import sys
7 | import time
8 | import signal
9 | import shlex
10 |
11 | try:
12 | from queue import Queue, Empty # Python 3
13 | except ImportError:
14 | from Queue import Queue, Empty # Python 2
15 |
16 | from .spawnbase import SpawnBase, PY3
17 | from .exceptions import EOF
18 | from .utils import string_types
19 |
20 | class PopenSpawn(SpawnBase):
21 | def __init__(self, cmd, timeout=30, maxread=2000, searchwindowsize=None,
22 | logfile=None, cwd=None, env=None, encoding=None,
23 | codec_errors='strict', preexec_fn=None):
24 | super(PopenSpawn, self).__init__(timeout=timeout, maxread=maxread,
25 | searchwindowsize=searchwindowsize, logfile=logfile,
26 | encoding=encoding, codec_errors=codec_errors)
27 |
28 | # Note that `SpawnBase` initializes `self.crlf` to `\r\n`
29 | # because the default behaviour for a PTY is to convert
30 | # incoming LF to `\r\n` (see the `onlcr` flag and
31 | # https://stackoverflow.com/a/35887657/5397009). Here we set
32 | # it to `os.linesep` because that is what the spawned
33 | # application outputs by default and `popen` doesn't translate
34 | # anything.
35 | if encoding is None:
36 | self.crlf = os.linesep.encode ("ascii")
37 | else:
38 | self.crlf = self.string_type (os.linesep)
39 |
40 | kwargs = dict(bufsize=0, stdin=subprocess.PIPE,
41 | stderr=subprocess.STDOUT, stdout=subprocess.PIPE,
42 | cwd=cwd, preexec_fn=preexec_fn, env=env)
43 |
44 | if sys.platform == 'win32':
45 | startupinfo = subprocess.STARTUPINFO()
46 | startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
47 | kwargs['startupinfo'] = startupinfo
48 | kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
49 |
50 | if isinstance(cmd, string_types) and sys.platform != 'win32':
51 | cmd = shlex.split(cmd, posix=os.name == 'posix')
52 |
53 | self.proc = subprocess.Popen(cmd, **kwargs)
54 | self.pid = self.proc.pid
55 | self.closed = False
56 | self._buf = self.string_type()
57 |
58 | self._read_queue = Queue()
59 | self._read_thread = threading.Thread(target=self._read_incoming)
60 | self._read_thread.setDaemon(True)
61 | self._read_thread.start()
62 |
63 | _read_reached_eof = False
64 |
65 | def read_nonblocking(self, size, timeout):
66 | buf = self._buf
67 | if self._read_reached_eof:
68 | # We have already finished reading. Use up any buffered data,
69 | # then raise EOF
70 | if buf:
71 | self._buf = buf[size:]
72 | return buf[:size]
73 | else:
74 | self.flag_eof = True
75 | raise EOF('End Of File (EOF).')
76 |
77 | if timeout == -1:
78 | timeout = self.timeout
79 | elif timeout is None:
80 | timeout = 1e6
81 |
82 | t0 = time.time()
83 | while (time.time() - t0) < timeout and size and len(buf) < size:
84 | try:
85 | incoming = self._read_queue.get_nowait()
86 | except Empty:
87 | break
88 | else:
89 | if incoming is None:
90 | self._read_reached_eof = True
91 | break
92 |
93 | buf += self._decoder.decode(incoming, final=False)
94 |
95 | r, self._buf = buf[:size], buf[size:]
96 |
97 | self._log(r, 'read')
98 | return r
99 |
100 | def _read_incoming(self):
101 | """Run in a thread to move output from a pipe to a queue."""
102 | fileno = self.proc.stdout.fileno()
103 | while 1:
104 | buf = b''
105 | try:
106 | buf = os.read(fileno, 1024)
107 | except OSError as e:
108 | self._log(e, 'read')
109 |
110 | if not buf:
111 | # This indicates we have reached EOF
112 | self._read_queue.put(None)
113 | return
114 |
115 | self._read_queue.put(buf)
116 |
117 | def write(self, s):
118 | '''This is similar to send() except that there is no return value.
119 | '''
120 | self.send(s)
121 |
122 | def writelines(self, sequence):
123 | '''This calls write() for each element in the sequence.
124 |
125 | The sequence can be any iterable object producing strings, typically a
126 | list of strings. This does not add line separators. There is no return
127 | value.
128 | '''
129 | for s in sequence:
130 | self.send(s)
131 |
132 | def send(self, s):
133 | '''Send data to the subprocess' stdin.
134 |
135 | Returns the number of bytes written.
136 | '''
137 | s = self._coerce_send_string(s)
138 | self._log(s, 'send')
139 |
140 | b = self._encoder.encode(s, final=False)
141 | if PY3:
142 | return self.proc.stdin.write(b)
143 | else:
144 | # On Python 2, .write() returns None, so we return the length of
145 | # bytes written ourselves. This assumes they all got written.
146 | self.proc.stdin.write(b)
147 | return len(b)
148 |
149 | def sendline(self, s=''):
150 | '''Wraps send(), sending string ``s`` to child process, with os.linesep
151 | automatically appended. Returns number of bytes written. '''
152 |
153 | n = self.send(s)
154 | return n + self.send(self.linesep)
155 |
156 | def wait(self):
157 | '''Wait for the subprocess to finish.
158 |
159 | Returns the exit code.
160 | '''
161 | status = self.proc.wait()
162 | if status >= 0:
163 | self.exitstatus = status
164 | self.signalstatus = None
165 | else:
166 | self.exitstatus = None
167 | self.signalstatus = -status
168 | self.terminated = True
169 | return status
170 |
171 | def kill(self, sig):
172 | '''Sends a Unix signal to the subprocess.
173 |
174 | Use constants from the :mod:`signal` module to specify which signal.
175 | '''
176 | if sys.platform == 'win32':
177 | if sig in [signal.SIGINT, signal.CTRL_C_EVENT]:
178 | sig = signal.CTRL_C_EVENT
179 | elif sig in [signal.SIGBREAK, signal.CTRL_BREAK_EVENT]:
180 | sig = signal.CTRL_BREAK_EVENT
181 | else:
182 | sig = signal.SIGTERM
183 |
184 | os.kill(self.proc.pid, sig)
185 |
186 | def sendeof(self):
187 | '''Closes the stdin pipe from the writing end.'''
188 | self.proc.stdin.close()
189 |
--------------------------------------------------------------------------------
/deps/pexpect/replwrap.py:
--------------------------------------------------------------------------------
1 | """Generic wrapper for read-eval-print-loops, a.k.a. interactive shells
2 | """
3 | import os.path
4 | import signal
5 | import sys
6 |
7 | import pexpect
8 |
9 | PY3 = (sys.version_info[0] >= 3)
10 |
11 | if PY3:
12 | basestring = str
13 |
14 | PEXPECT_PROMPT = u'[PEXPECT_PROMPT>'
15 | PEXPECT_CONTINUATION_PROMPT = u'[PEXPECT_PROMPT+'
16 |
17 | class REPLWrapper(object):
18 | """Wrapper for a REPL.
19 |
20 | :param cmd_or_spawn: This can either be an instance of :class:`pexpect.spawn`
21 | in which a REPL has already been started, or a str command to start a new
22 | REPL process.
23 | :param str orig_prompt: The prompt to expect at first.
24 | :param str prompt_change: A command to change the prompt to something more
25 | unique. If this is ``None``, the prompt will not be changed. This will
26 | be formatted with the new and continuation prompts as positional
27 | parameters, so you can use ``{}`` style formatting to insert them into
28 | the command.
29 | :param str new_prompt: The more unique prompt to expect after the change.
30 | :param str extra_init_cmd: Commands to do extra initialisation, such as
31 | disabling pagers.
32 | """
33 | def __init__(self, cmd_or_spawn, orig_prompt, prompt_change,
34 | new_prompt=PEXPECT_PROMPT,
35 | continuation_prompt=PEXPECT_CONTINUATION_PROMPT,
36 | extra_init_cmd=None):
37 | if isinstance(cmd_or_spawn, basestring):
38 | self.child = pexpect.spawn(cmd_or_spawn, echo=False, encoding='utf-8')
39 | else:
40 | self.child = cmd_or_spawn
41 | if self.child.echo:
42 | # Existing spawn instance has echo enabled, disable it
43 | # to prevent our input from being repeated to output.
44 | self.child.setecho(False)
45 | self.child.waitnoecho()
46 |
47 | if prompt_change is None:
48 | self.prompt = orig_prompt
49 | else:
50 | self.set_prompt(orig_prompt,
51 | prompt_change.format(new_prompt, continuation_prompt))
52 | self.prompt = new_prompt
53 | self.continuation_prompt = continuation_prompt
54 |
55 | self._expect_prompt()
56 |
57 | if extra_init_cmd is not None:
58 | self.run_command(extra_init_cmd)
59 |
60 | def set_prompt(self, orig_prompt, prompt_change):
61 | self.child.expect(orig_prompt)
62 | self.child.sendline(prompt_change)
63 |
64 | def _expect_prompt(self, timeout=-1, async_=False):
65 | return self.child.expect_exact([self.prompt, self.continuation_prompt],
66 | timeout=timeout, async_=async_)
67 |
68 | def run_command(self, command, timeout=-1, async_=False):
69 | """Send a command to the REPL, wait for and return output.
70 |
71 | :param str command: The command to send. Trailing newlines are not needed.
72 | This should be a complete block of input that will trigger execution;
73 | if a continuation prompt is found after sending input, :exc:`ValueError`
74 | will be raised.
75 | :param int timeout: How long to wait for the next prompt. -1 means the
76 | default from the :class:`pexpect.spawn` object (default 30 seconds).
77 | None means to wait indefinitely.
78 | :param bool async_: On Python 3.4, or Python 3.3 with asyncio
79 | installed, passing ``async_=True`` will make this return an
80 | :mod:`asyncio` Future, which you can yield from to get the same
81 | result that this method would normally give directly.
82 | """
83 | # Split up multiline commands and feed them in bit-by-bit
84 | cmdlines = command.splitlines()
85 | # splitlines ignores trailing newlines - add it back in manually
86 | if command.endswith('\n'):
87 | cmdlines.append('')
88 | if not cmdlines:
89 | raise ValueError("No command was given")
90 |
91 | if async_:
92 | from ._async import repl_run_command_async
93 | return repl_run_command_async(self, cmdlines, timeout)
94 |
95 | res = []
96 | self.child.sendline(cmdlines[0])
97 | for line in cmdlines[1:]:
98 | self._expect_prompt(timeout=timeout)
99 | res.append(self.child.before)
100 | self.child.sendline(line)
101 |
102 | # Command was fully submitted, now wait for the next prompt
103 | if self._expect_prompt(timeout=timeout) == 1:
104 | # We got the continuation prompt - command was incomplete
105 | self.child.kill(signal.SIGINT)
106 | self._expect_prompt(timeout=1)
107 | raise ValueError("Continuation prompt found - input was incomplete:\n"
108 | + command)
109 | return u''.join(res + [self.child.before])
110 |
111 | def python(command="python"):
112 | """Start a Python shell and return a :class:`REPLWrapper` object."""
113 | return REPLWrapper(command, u">>> ", u"import sys; sys.ps1={0!r}; sys.ps2={1!r}")
114 |
115 | def bash(command="bash"):
116 | """Start a bash shell and return a :class:`REPLWrapper` object."""
117 | bashrc = os.path.join(os.path.dirname(__file__), 'bashrc.sh')
118 | child = pexpect.spawn(command, ['--rcfile', bashrc], echo=False,
119 | encoding='utf-8')
120 |
121 | # If the user runs 'env', the value of PS1 will be in the output. To avoid
122 | # replwrap seeing that as the next prompt, we'll embed the marker characters
123 | # for invisible characters in the prompt; these show up when inspecting the
124 | # environment variable, but not when bash displays the prompt.
125 | ps1 = PEXPECT_PROMPT[:5] + u'\\[\\]' + PEXPECT_PROMPT[5:]
126 | ps2 = PEXPECT_CONTINUATION_PROMPT[:5] + u'\\[\\]' + PEXPECT_CONTINUATION_PROMPT[5:]
127 | prompt_change = u"PS1='{0}' PS2='{1}' PROMPT_COMMAND=''".format(ps1, ps2)
128 |
129 | return REPLWrapper(child, u'\\$', prompt_change,
130 | extra_init_cmd="export PAGER=cat")
131 |
--------------------------------------------------------------------------------
/deps/pexpect/run.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import types
3 |
4 | from .exceptions import EOF, TIMEOUT
5 | from .pty_spawn import spawn
6 |
7 | def run(command, timeout=30, withexitstatus=False, events=None,
8 | extra_args=None, logfile=None, cwd=None, env=None, **kwargs):
9 |
10 | '''
11 | This function runs the given command; waits for it to finish; then
12 | returns all output as a string. STDERR is included in output. If the full
13 | path to the command is not given then the path is searched.
14 |
15 | Note that lines are terminated by CR/LF (\\r\\n) combination even on
16 | UNIX-like systems because this is the standard for pseudottys. If you set
17 | 'withexitstatus' to true, then run will return a tuple of (command_output,
18 | exitstatus). If 'withexitstatus' is false then this returns just
19 | command_output.
20 |
21 | The run() function can often be used instead of creating a spawn instance.
22 | For example, the following code uses spawn::
23 |
24 | from pexpect import *
25 | child = spawn('scp foo user@example.com:.')
26 | child.expect('(?i)password')
27 | child.sendline(mypassword)
28 |
29 | The previous code can be replace with the following::
30 |
31 | from pexpect import *
32 | run('scp foo user@example.com:.', events={'(?i)password': mypassword})
33 |
34 | **Examples**
35 |
36 | Start the apache daemon on the local machine::
37 |
38 | from pexpect import *
39 | run("/usr/local/apache/bin/apachectl start")
40 |
41 | Check in a file using SVN::
42 |
43 | from pexpect import *
44 | run("svn ci -m 'automatic commit' my_file.py")
45 |
46 | Run a command and capture exit status::
47 |
48 | from pexpect import *
49 | (command_output, exitstatus) = run('ls -l /bin', withexitstatus=1)
50 |
51 | The following will run SSH and execute 'ls -l' on the remote machine. The
52 | password 'secret' will be sent if the '(?i)password' pattern is ever seen::
53 |
54 | run("ssh username@machine.example.com 'ls -l'",
55 | events={'(?i)password':'secret\\n'})
56 |
57 | This will start mencoder to rip a video from DVD. This will also display
58 | progress ticks every 5 seconds as it runs. For example::
59 |
60 | from pexpect import *
61 | def print_ticks(d):
62 | print d['event_count'],
63 | run("mencoder dvd://1 -o video.avi -oac copy -ovc copy",
64 | events={TIMEOUT:print_ticks}, timeout=5)
65 |
66 | The 'events' argument should be either a dictionary or a tuple list that
67 | contains patterns and responses. Whenever one of the patterns is seen
68 | in the command output, run() will send the associated response string.
69 | So, run() in the above example can be also written as:
70 |
71 | run("mencoder dvd://1 -o video.avi -oac copy -ovc copy",
72 | events=[(TIMEOUT,print_ticks)], timeout=5)
73 |
74 | Use a tuple list for events if the command output requires a delicate
75 | control over what pattern should be matched, since the tuple list is passed
76 | to pexpect() as its pattern list, with the order of patterns preserved.
77 |
78 | Note that you should put newlines in your string if Enter is necessary.
79 |
80 | Like the example above, the responses may also contain a callback, either
81 | a function or method. It should accept a dictionary value as an argument.
82 | The dictionary contains all the locals from the run() function, so you can
83 | access the child spawn object or any other variable defined in run()
84 | (event_count, child, and extra_args are the most useful). A callback may
85 | return True to stop the current run process. Otherwise run() continues
86 | until the next event. A callback may also return a string which will be
87 | sent to the child. 'extra_args' is not used by directly run(). It provides
88 | a way to pass data to a callback function through run() through the locals
89 | dictionary passed to a callback.
90 |
91 | Like :class:`spawn`, passing *encoding* will make it work with unicode
92 | instead of bytes. You can pass *codec_errors* to control how errors in
93 | encoding and decoding are handled.
94 | '''
95 | if timeout == -1:
96 | child = spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env,
97 | **kwargs)
98 | else:
99 | child = spawn(command, timeout=timeout, maxread=2000, logfile=logfile,
100 | cwd=cwd, env=env, **kwargs)
101 | if isinstance(events, list):
102 | patterns= [x for x,y in events]
103 | responses = [y for x,y in events]
104 | elif isinstance(events, dict):
105 | patterns = list(events.keys())
106 | responses = list(events.values())
107 | else:
108 | # This assumes EOF or TIMEOUT will eventually cause run to terminate.
109 | patterns = None
110 | responses = None
111 | child_result_list = []
112 | event_count = 0
113 | while True:
114 | try:
115 | index = child.expect(patterns)
116 | if isinstance(child.after, child.allowed_string_types):
117 | child_result_list.append(child.before + child.after)
118 | else:
119 | # child.after may have been a TIMEOUT or EOF,
120 | # which we don't want appended to the list.
121 | child_result_list.append(child.before)
122 | if isinstance(responses[index], child.allowed_string_types):
123 | child.send(responses[index])
124 | elif (isinstance(responses[index], types.FunctionType) or
125 | isinstance(responses[index], types.MethodType)):
126 | callback_result = responses[index](locals())
127 | sys.stdout.flush()
128 | if isinstance(callback_result, child.allowed_string_types):
129 | child.send(callback_result)
130 | elif callback_result:
131 | break
132 | else:
133 | raise TypeError("parameter `event' at index {index} must be "
134 | "a string, method, or function: {value!r}"
135 | .format(index=index, value=responses[index]))
136 | event_count = event_count + 1
137 | except TIMEOUT:
138 | child_result_list.append(child.before)
139 | break
140 | except EOF:
141 | child_result_list.append(child.before)
142 | break
143 | child_result = child.string_type().join(child_result_list)
144 | if withexitstatus:
145 | child.close()
146 | return (child_result, child.exitstatus)
147 | else:
148 | return child_result
149 |
150 | def runu(command, timeout=30, withexitstatus=False, events=None,
151 | extra_args=None, logfile=None, cwd=None, env=None, **kwargs):
152 | """Deprecated: pass encoding to run() instead.
153 | """
154 | kwargs.setdefault('encoding', 'utf-8')
155 | return run(command, timeout=timeout, withexitstatus=withexitstatus,
156 | events=events, extra_args=extra_args, logfile=logfile, cwd=cwd,
157 | env=env, **kwargs)
158 |
--------------------------------------------------------------------------------
/deps/pexpect/screen.py:
--------------------------------------------------------------------------------
1 | '''This implements a virtual screen. This is used to support ANSI terminal
2 | emulation. The screen representation and state is implemented in this class.
3 | Most of the methods are inspired by ANSI screen control codes. The
4 | :class:`~pexpect.ANSI.ANSI` class extends this class to add parsing of ANSI
5 | escape codes.
6 |
7 | PEXPECT LICENSE
8 |
9 | This license is approved by the OSI and FSF as GPL-compatible.
10 | http://opensource.org/licenses/isc-license.txt
11 |
12 | Copyright (c) 2012, Noah Spurrier
13 | PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
14 | PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
15 | COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
16 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 |
24 | '''
25 |
26 | import codecs
27 | import copy
28 | import sys
29 |
30 | import warnings
31 |
32 | warnings.warn(("pexpect.screen and pexpect.ANSI are deprecated. "
33 | "We recommend using pyte to emulate a terminal screen: "
34 | "https://pypi.python.org/pypi/pyte"),
35 | stacklevel=2)
36 |
37 | NUL = 0 # Fill character; ignored on input.
38 | ENQ = 5 # Transmit answerback message.
39 | BEL = 7 # Ring the bell.
40 | BS = 8 # Move cursor left.
41 | HT = 9 # Move cursor to next tab stop.
42 | LF = 10 # Line feed.
43 | VT = 11 # Same as LF.
44 | FF = 12 # Same as LF.
45 | CR = 13 # Move cursor to left margin or newline.
46 | SO = 14 # Invoke G1 character set.
47 | SI = 15 # Invoke G0 character set.
48 | XON = 17 # Resume transmission.
49 | XOFF = 19 # Halt transmission.
50 | CAN = 24 # Cancel escape sequence.
51 | SUB = 26 # Same as CAN.
52 | ESC = 27 # Introduce a control sequence.
53 | DEL = 127 # Fill character; ignored on input.
54 | SPACE = u' ' # Space or blank character.
55 |
56 | PY3 = (sys.version_info[0] >= 3)
57 | if PY3:
58 | unicode = str
59 |
60 | def constrain (n, min, max):
61 |
62 | '''This returns a number, n constrained to the min and max bounds. '''
63 |
64 | if n < min:
65 | return min
66 | if n > max:
67 | return max
68 | return n
69 |
70 | class screen:
71 | '''This object maintains the state of a virtual text screen as a
72 | rectangular array. This maintains a virtual cursor position and handles
73 | scrolling as characters are added. This supports most of the methods needed
74 | by an ANSI text screen. Row and column indexes are 1-based (not zero-based,
75 | like arrays).
76 |
77 | Characters are represented internally using unicode. Methods that accept
78 | input characters, when passed 'bytes' (which in Python 2 is equivalent to
79 | 'str'), convert them from the encoding specified in the 'encoding'
80 | parameter to the constructor. Methods that return screen contents return
81 | unicode strings, with the exception of __str__() under Python 2. Passing
82 | ``encoding=None`` limits the API to only accept unicode input, so passing
83 | bytes in will raise :exc:`TypeError`.
84 | '''
85 | def __init__(self, r=24, c=80, encoding='latin-1', encoding_errors='replace'):
86 | '''This initializes a blank screen of the given dimensions.'''
87 |
88 | self.rows = r
89 | self.cols = c
90 | self.encoding = encoding
91 | self.encoding_errors = encoding_errors
92 | if encoding is not None:
93 | self.decoder = codecs.getincrementaldecoder(encoding)(encoding_errors)
94 | else:
95 | self.decoder = None
96 | self.cur_r = 1
97 | self.cur_c = 1
98 | self.cur_saved_r = 1
99 | self.cur_saved_c = 1
100 | self.scroll_row_start = 1
101 | self.scroll_row_end = self.rows
102 | self.w = [ [SPACE] * self.cols for _ in range(self.rows)]
103 |
104 | def _decode(self, s):
105 | '''This converts from the external coding system (as passed to
106 | the constructor) to the internal one (unicode). '''
107 | if self.decoder is not None:
108 | return self.decoder.decode(s)
109 | else:
110 | raise TypeError("This screen was constructed with encoding=None, "
111 | "so it does not handle bytes.")
112 |
113 | def _unicode(self):
114 | '''This returns a printable representation of the screen as a unicode
115 | string (which, under Python 3.x, is the same as 'str'). The end of each
116 | screen line is terminated by a newline.'''
117 |
118 | return u'\n'.join ([ u''.join(c) for c in self.w ])
119 |
120 | if PY3:
121 | __str__ = _unicode
122 | else:
123 | __unicode__ = _unicode
124 |
125 | def __str__(self):
126 | '''This returns a printable representation of the screen. The end of
127 | each screen line is terminated by a newline. '''
128 | encoding = self.encoding or 'ascii'
129 | return self._unicode().encode(encoding, 'replace')
130 |
131 | def dump (self):
132 | '''This returns a copy of the screen as a unicode string. This is similar to
133 | __str__/__unicode__ except that lines are not terminated with line
134 | feeds.'''
135 |
136 | return u''.join ([ u''.join(c) for c in self.w ])
137 |
138 | def pretty (self):
139 | '''This returns a copy of the screen as a unicode string with an ASCII
140 | text box around the screen border. This is similar to
141 | __str__/__unicode__ except that it adds a box.'''
142 |
143 | top_bot = u'+' + u'-'*self.cols + u'+\n'
144 | return top_bot + u'\n'.join([u'|'+line+u'|' for line in unicode(self).split(u'\n')]) + u'\n' + top_bot
145 |
146 | def fill (self, ch=SPACE):
147 |
148 | if isinstance(ch, bytes):
149 | ch = self._decode(ch)
150 |
151 | self.fill_region (1,1,self.rows,self.cols, ch)
152 |
153 | def fill_region (self, rs,cs, re,ce, ch=SPACE):
154 |
155 | if isinstance(ch, bytes):
156 | ch = self._decode(ch)
157 |
158 | rs = constrain (rs, 1, self.rows)
159 | re = constrain (re, 1, self.rows)
160 | cs = constrain (cs, 1, self.cols)
161 | ce = constrain (ce, 1, self.cols)
162 | if rs > re:
163 | rs, re = re, rs
164 | if cs > ce:
165 | cs, ce = ce, cs
166 | for r in range (rs, re+1):
167 | for c in range (cs, ce + 1):
168 | self.put_abs (r,c,ch)
169 |
170 | def cr (self):
171 | '''This moves the cursor to the beginning (col 1) of the current row.
172 | '''
173 |
174 | self.cursor_home (self.cur_r, 1)
175 |
176 | def lf (self):
177 | '''This moves the cursor down with scrolling.
178 | '''
179 |
180 | old_r = self.cur_r
181 | self.cursor_down()
182 | if old_r == self.cur_r:
183 | self.scroll_up ()
184 | self.erase_line()
185 |
186 | def crlf (self):
187 | '''This advances the cursor with CRLF properties.
188 | The cursor will line wrap and the screen may scroll.
189 | '''
190 |
191 | self.cr ()
192 | self.lf ()
193 |
194 | def newline (self):
195 | '''This is an alias for crlf().
196 | '''
197 |
198 | self.crlf()
199 |
200 | def put_abs (self, r, c, ch):
201 | '''Screen array starts at 1 index.'''
202 |
203 | r = constrain (r, 1, self.rows)
204 | c = constrain (c, 1, self.cols)
205 | if isinstance(ch, bytes):
206 | ch = self._decode(ch)[0]
207 | else:
208 | ch = ch[0]
209 | self.w[r-1][c-1] = ch
210 |
211 | def put (self, ch):
212 | '''This puts a characters at the current cursor position.
213 | '''
214 |
215 | if isinstance(ch, bytes):
216 | ch = self._decode(ch)
217 |
218 | self.put_abs (self.cur_r, self.cur_c, ch)
219 |
220 | def insert_abs (self, r, c, ch):
221 | '''This inserts a character at (r,c). Everything under
222 | and to the right is shifted right one character.
223 | The last character of the line is lost.
224 | '''
225 |
226 | if isinstance(ch, bytes):
227 | ch = self._decode(ch)
228 |
229 | r = constrain (r, 1, self.rows)
230 | c = constrain (c, 1, self.cols)
231 | for ci in range (self.cols, c, -1):
232 | self.put_abs (r,ci, self.get_abs(r,ci-1))
233 | self.put_abs (r,c,ch)
234 |
235 | def insert (self, ch):
236 |
237 | if isinstance(ch, bytes):
238 | ch = self._decode(ch)
239 |
240 | self.insert_abs (self.cur_r, self.cur_c, ch)
241 |
242 | def get_abs (self, r, c):
243 |
244 | r = constrain (r, 1, self.rows)
245 | c = constrain (c, 1, self.cols)
246 | return self.w[r-1][c-1]
247 |
248 | def get (self):
249 |
250 | self.get_abs (self.cur_r, self.cur_c)
251 |
252 | def get_region (self, rs,cs, re,ce):
253 | '''This returns a list of lines representing the region.
254 | '''
255 |
256 | rs = constrain (rs, 1, self.rows)
257 | re = constrain (re, 1, self.rows)
258 | cs = constrain (cs, 1, self.cols)
259 | ce = constrain (ce, 1, self.cols)
260 | if rs > re:
261 | rs, re = re, rs
262 | if cs > ce:
263 | cs, ce = ce, cs
264 | sc = []
265 | for r in range (rs, re+1):
266 | line = u''
267 | for c in range (cs, ce + 1):
268 | ch = self.get_abs (r,c)
269 | line = line + ch
270 | sc.append (line)
271 | return sc
272 |
273 | def cursor_constrain (self):
274 | '''This keeps the cursor within the screen area.
275 | '''
276 |
277 | self.cur_r = constrain (self.cur_r, 1, self.rows)
278 | self.cur_c = constrain (self.cur_c, 1, self.cols)
279 |
280 | def cursor_home (self, r=1, c=1): # [{ROW};{COLUMN}H
281 |
282 | self.cur_r = r
283 | self.cur_c = c
284 | self.cursor_constrain ()
285 |
286 | def cursor_back (self,count=1): # [{COUNT}D (not confused with down)
287 |
288 | self.cur_c = self.cur_c - count
289 | self.cursor_constrain ()
290 |
291 | def cursor_down (self,count=1): # [{COUNT}B (not confused with back)
292 |
293 | self.cur_r = self.cur_r + count
294 | self.cursor_constrain ()
295 |
296 | def cursor_forward (self,count=1): # [{COUNT}C
297 |
298 | self.cur_c = self.cur_c + count
299 | self.cursor_constrain ()
300 |
301 | def cursor_up (self,count=1): # [{COUNT}A
302 |
303 | self.cur_r = self.cur_r - count
304 | self.cursor_constrain ()
305 |
306 | def cursor_up_reverse (self): # M (called RI -- Reverse Index)
307 |
308 | old_r = self.cur_r
309 | self.cursor_up()
310 | if old_r == self.cur_r:
311 | self.scroll_up()
312 |
313 | def cursor_force_position (self, r, c): # [{ROW};{COLUMN}f
314 | '''Identical to Cursor Home.'''
315 |
316 | self.cursor_home (r, c)
317 |
318 | def cursor_save (self): # [s
319 | '''Save current cursor position.'''
320 |
321 | self.cursor_save_attrs()
322 |
323 | def cursor_unsave (self): # [u
324 | '''Restores cursor position after a Save Cursor.'''
325 |
326 | self.cursor_restore_attrs()
327 |
328 | def cursor_save_attrs (self): # 7
329 | '''Save current cursor position.'''
330 |
331 | self.cur_saved_r = self.cur_r
332 | self.cur_saved_c = self.cur_c
333 |
334 | def cursor_restore_attrs (self): # 8
335 | '''Restores cursor position after a Save Cursor.'''
336 |
337 | self.cursor_home (self.cur_saved_r, self.cur_saved_c)
338 |
339 | def scroll_constrain (self):
340 | '''This keeps the scroll region within the screen region.'''
341 |
342 | if self.scroll_row_start <= 0:
343 | self.scroll_row_start = 1
344 | if self.scroll_row_end > self.rows:
345 | self.scroll_row_end = self.rows
346 |
347 | def scroll_screen (self): # [r
348 | '''Enable scrolling for entire display.'''
349 |
350 | self.scroll_row_start = 1
351 | self.scroll_row_end = self.rows
352 |
353 | def scroll_screen_rows (self, rs, re): # [{start};{end}r
354 | '''Enable scrolling from row {start} to row {end}.'''
355 |
356 | self.scroll_row_start = rs
357 | self.scroll_row_end = re
358 | self.scroll_constrain()
359 |
360 | def scroll_down (self): # D
361 | '''Scroll display down one line.'''
362 |
363 | # Screen is indexed from 1, but arrays are indexed from 0.
364 | s = self.scroll_row_start - 1
365 | e = self.scroll_row_end - 1
366 | self.w[s+1:e+1] = copy.deepcopy(self.w[s:e])
367 |
368 | def scroll_up (self): # M
369 | '''Scroll display up one line.'''
370 |
371 | # Screen is indexed from 1, but arrays are indexed from 0.
372 | s = self.scroll_row_start - 1
373 | e = self.scroll_row_end - 1
374 | self.w[s:e] = copy.deepcopy(self.w[s+1:e+1])
375 |
376 | def erase_end_of_line (self): # [0K -or- [K
377 | '''Erases from the current cursor position to the end of the current
378 | line.'''
379 |
380 | self.fill_region (self.cur_r, self.cur_c, self.cur_r, self.cols)
381 |
382 | def erase_start_of_line (self): # [1K
383 | '''Erases from the current cursor position to the start of the current
384 | line.'''
385 |
386 | self.fill_region (self.cur_r, 1, self.cur_r, self.cur_c)
387 |
388 | def erase_line (self): # [2K
389 | '''Erases the entire current line.'''
390 |
391 | self.fill_region (self.cur_r, 1, self.cur_r, self.cols)
392 |
393 | def erase_down (self): # [0J -or- [J
394 | '''Erases the screen from the current line down to the bottom of the
395 | screen.'''
396 |
397 | self.erase_end_of_line ()
398 | self.fill_region (self.cur_r + 1, 1, self.rows, self.cols)
399 |
400 | def erase_up (self): # [1J
401 | '''Erases the screen from the current line up to the top of the
402 | screen.'''
403 |
404 | self.erase_start_of_line ()
405 | self.fill_region (self.cur_r-1, 1, 1, self.cols)
406 |
407 | def erase_screen (self): # [2J
408 | '''Erases the screen with the background color.'''
409 |
410 | self.fill ()
411 |
412 | def set_tab (self): # H
413 | '''Sets a tab at the current position.'''
414 |
415 | pass
416 |
417 | def clear_tab (self): # [g
418 | '''Clears tab at the current position.'''
419 |
420 | pass
421 |
422 | def clear_all_tabs (self): # [3g
423 | '''Clears all tabs.'''
424 |
425 | pass
426 |
427 | # Insert line Esc [ Pn L
428 | # Delete line Esc [ Pn M
429 | # Delete character Esc [ Pn P
430 | # Scrolling region Esc [ Pn(top);Pn(bot) r
431 |
432 |
--------------------------------------------------------------------------------
/deps/pexpect/utils.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | import stat
4 | import select
5 | import time
6 | import errno
7 |
8 | try:
9 | InterruptedError
10 | except NameError:
11 | # Alias Python2 exception to Python3
12 | InterruptedError = select.error
13 |
14 | if sys.version_info[0] >= 3:
15 | string_types = (str,)
16 | else:
17 | string_types = (unicode, str)
18 |
19 |
20 | def is_executable_file(path):
21 | """Checks that path is an executable regular file, or a symlink towards one.
22 |
23 | This is roughly ``os.path isfile(path) and os.access(path, os.X_OK)``.
24 | """
25 | # follow symlinks,
26 | fpath = os.path.realpath(path)
27 |
28 | if not os.path.isfile(fpath):
29 | # non-files (directories, fifo, etc.)
30 | return False
31 |
32 | mode = os.stat(fpath).st_mode
33 |
34 | if (sys.platform.startswith('sunos')
35 | and os.getuid() == 0):
36 | # When root on Solaris, os.X_OK is True for *all* files, irregardless
37 | # of their executability -- instead, any permission bit of any user,
38 | # group, or other is fine enough.
39 | #
40 | # (This may be true for other "Unix98" OS's such as HP-UX and AIX)
41 | return bool(mode & (stat.S_IXUSR |
42 | stat.S_IXGRP |
43 | stat.S_IXOTH))
44 |
45 | return os.access(fpath, os.X_OK)
46 |
47 |
48 | def which(filename, env=None):
49 | '''This takes a given filename; tries to find it in the environment path;
50 | then checks if it is executable. This returns the full path to the filename
51 | if found and executable. Otherwise this returns None.'''
52 |
53 | # Special case where filename contains an explicit path.
54 | if os.path.dirname(filename) != '' and is_executable_file(filename):
55 | return filename
56 | if env is None:
57 | env = os.environ
58 | p = env.get('PATH')
59 | if not p:
60 | p = os.defpath
61 | pathlist = p.split(os.pathsep)
62 | for path in pathlist:
63 | ff = os.path.join(path, filename)
64 | if is_executable_file(ff):
65 | return ff
66 | return None
67 |
68 |
69 | def split_command_line(command_line):
70 |
71 | '''This splits a command line into a list of arguments. It splits arguments
72 | on spaces, but handles embedded quotes, doublequotes, and escaped
73 | characters. It's impossible to do this with a regular expression, so I
74 | wrote a little state machine to parse the command line. '''
75 |
76 | arg_list = []
77 | arg = ''
78 |
79 | # Constants to name the states we can be in.
80 | state_basic = 0
81 | state_esc = 1
82 | state_singlequote = 2
83 | state_doublequote = 3
84 | # The state when consuming whitespace between commands.
85 | state_whitespace = 4
86 | state = state_basic
87 |
88 | for c in command_line:
89 | if state == state_basic or state == state_whitespace:
90 | if c == '\\':
91 | # Escape the next character
92 | state = state_esc
93 | elif c == r"'":
94 | # Handle single quote
95 | state = state_singlequote
96 | elif c == r'"':
97 | # Handle double quote
98 | state = state_doublequote
99 | elif c.isspace():
100 | # Add arg to arg_list if we aren't in the middle of whitespace.
101 | if state == state_whitespace:
102 | # Do nothing.
103 | None
104 | else:
105 | arg_list.append(arg)
106 | arg = ''
107 | state = state_whitespace
108 | else:
109 | arg = arg + c
110 | state = state_basic
111 | elif state == state_esc:
112 | arg = arg + c
113 | state = state_basic
114 | elif state == state_singlequote:
115 | if c == r"'":
116 | state = state_basic
117 | else:
118 | arg = arg + c
119 | elif state == state_doublequote:
120 | if c == r'"':
121 | state = state_basic
122 | else:
123 | arg = arg + c
124 |
125 | if arg != '':
126 | arg_list.append(arg)
127 | return arg_list
128 |
129 |
130 | def select_ignore_interrupts(iwtd, owtd, ewtd, timeout=None):
131 |
132 | '''This is a wrapper around select.select() that ignores signals. If
133 | select.select raises a select.error exception and errno is an EINTR
134 | error then it is ignored. Mainly this is used to ignore sigwinch
135 | (terminal resize). '''
136 |
137 | # if select() is interrupted by a signal (errno==EINTR) then
138 | # we loop back and enter the select() again.
139 | if timeout is not None:
140 | end_time = time.time() + timeout
141 | while True:
142 | try:
143 | return select.select(iwtd, owtd, ewtd, timeout)
144 | except InterruptedError:
145 | err = sys.exc_info()[1]
146 | if err.args[0] == errno.EINTR:
147 | # if we loop back we have to subtract the
148 | # amount of time we already waited.
149 | if timeout is not None:
150 | timeout = end_time - time.time()
151 | if timeout < 0:
152 | return([], [], [])
153 | else:
154 | # something else caused the select.error, so
155 | # this actually is an exception.
156 | raise
157 |
158 |
159 | def poll_ignore_interrupts(fds, timeout=None):
160 | '''Simple wrapper around poll to register file descriptors and
161 | ignore signals.'''
162 |
163 | if timeout is not None:
164 | end_time = time.time() + timeout
165 |
166 | poller = select.poll()
167 | for fd in fds:
168 | poller.register(fd, select.POLLIN | select.POLLPRI | select.POLLHUP | select.POLLERR)
169 |
170 | while True:
171 | try:
172 | timeout_ms = None if timeout is None else timeout * 1000
173 | results = poller.poll(timeout_ms)
174 | return [afd for afd, _ in results]
175 | except InterruptedError:
176 | err = sys.exc_info()[1]
177 | if err.args[0] == errno.EINTR:
178 | # if we loop back we have to subtract the
179 | # amount of time we already waited.
180 | if timeout is not None:
181 | timeout = end_time - time.time()
182 | if timeout < 0:
183 | return []
184 | else:
185 | # something else caused the select.error, so
186 | # this actually is an exception.
187 | raise
188 |
--------------------------------------------------------------------------------
/deps/ptyprocess/__init__.py:
--------------------------------------------------------------------------------
1 | """Run a subprocess in a pseudo terminal"""
2 | from .ptyprocess import PtyProcess, PtyProcessUnicode, PtyProcessError
3 |
4 | __version__ = '0.7.0'
5 |
--------------------------------------------------------------------------------
/deps/ptyprocess/_fork_pty.py:
--------------------------------------------------------------------------------
1 | """Substitute for the forkpty system call, to support Solaris.
2 | """
3 | import os
4 | import errno
5 |
6 | from pty import (STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, CHILD)
7 | from .util import PtyProcessError
8 |
9 | def fork_pty():
10 | '''This implements a substitute for the forkpty system call. This
11 | should be more portable than the pty.fork() function. Specifically,
12 | this should work on Solaris.
13 |
14 | Modified 10.06.05 by Geoff Marshall: Implemented __fork_pty() method to
15 | resolve the issue with Python's pty.fork() not supporting Solaris,
16 | particularly ssh. Based on patch to posixmodule.c authored by Noah
17 | Spurrier::
18 |
19 | http://mail.python.org/pipermail/python-dev/2003-May/035281.html
20 |
21 | '''
22 |
23 | parent_fd, child_fd = os.openpty()
24 | if parent_fd < 0 or child_fd < 0:
25 | raise OSError("os.openpty() failed")
26 |
27 | pid = os.fork()
28 | if pid == CHILD:
29 | # Child.
30 | os.close(parent_fd)
31 | pty_make_controlling_tty(child_fd)
32 |
33 | os.dup2(child_fd, STDIN_FILENO)
34 | os.dup2(child_fd, STDOUT_FILENO)
35 | os.dup2(child_fd, STDERR_FILENO)
36 |
37 | else:
38 | # Parent.
39 | os.close(child_fd)
40 |
41 | return pid, parent_fd
42 |
43 | def pty_make_controlling_tty(tty_fd):
44 | '''This makes the pseudo-terminal the controlling tty. This should be
45 | more portable than the pty.fork() function. Specifically, this should
46 | work on Solaris. '''
47 |
48 | child_name = os.ttyname(tty_fd)
49 |
50 | # Disconnect from controlling tty, if any. Raises OSError of ENXIO
51 | # if there was no controlling tty to begin with, such as when
52 | # executed by a cron(1) job.
53 | try:
54 | fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
55 | os.close(fd)
56 | except OSError as err:
57 | if err.errno != errno.ENXIO:
58 | raise
59 |
60 | os.setsid()
61 |
62 | # Verify we are disconnected from controlling tty by attempting to open
63 | # it again. We expect that OSError of ENXIO should always be raised.
64 | try:
65 | fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
66 | os.close(fd)
67 | raise PtyProcessError("OSError of errno.ENXIO should be raised.")
68 | except OSError as err:
69 | if err.errno != errno.ENXIO:
70 | raise
71 |
72 | # Verify we can open child pty.
73 | fd = os.open(child_name, os.O_RDWR)
74 | os.close(fd)
75 |
76 | # Verify we now have a controlling tty.
77 | fd = os.open("/dev/tty", os.O_WRONLY)
78 | os.close(fd)
79 |
--------------------------------------------------------------------------------
/deps/ptyprocess/util.py:
--------------------------------------------------------------------------------
1 | try:
2 | from shutil import which # Python >= 3.3
3 | except ImportError:
4 | import os, sys
5 |
6 | # This is copied from Python 3.4.1
7 | def which(cmd, mode=os.F_OK | os.X_OK, path=None):
8 | """Given a command, mode, and a PATH string, return the path which
9 | conforms to the given mode on the PATH, or None if there is no such
10 | file.
11 |
12 | `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
13 | of os.environ.get("PATH"), or can be overridden with a custom search
14 | path.
15 |
16 | """
17 | # Check that a given file can be accessed with the correct mode.
18 | # Additionally check that `file` is not a directory, as on Windows
19 | # directories pass the os.access check.
20 | def _access_check(fn, mode):
21 | return (os.path.exists(fn) and os.access(fn, mode)
22 | and not os.path.isdir(fn))
23 |
24 | # If we're given a path with a directory part, look it up directly rather
25 | # than referring to PATH directories. This includes checking relative to the
26 | # current directory, e.g. ./script
27 | if os.path.dirname(cmd):
28 | if _access_check(cmd, mode):
29 | return cmd
30 | return None
31 |
32 | if path is None:
33 | path = os.environ.get("PATH", os.defpath)
34 | if not path:
35 | return None
36 | path = path.split(os.pathsep)
37 |
38 | if sys.platform == "win32":
39 | # The current directory takes precedence on Windows.
40 | if not os.curdir in path:
41 | path.insert(0, os.curdir)
42 |
43 | # PATHEXT is necessary to check on Windows.
44 | pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
45 | # See if the given file matches any of the expected path extensions.
46 | # This will allow us to short circuit when given "python.exe".
47 | # If it does match, only test that one, otherwise we have to try
48 | # others.
49 | if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
50 | files = [cmd]
51 | else:
52 | files = [cmd + ext for ext in pathext]
53 | else:
54 | # On other platforms you don't have things like PATHEXT to tell you
55 | # what file suffixes are executable, so just pass on cmd as-is.
56 | files = [cmd]
57 |
58 | seen = set()
59 | for dir in path:
60 | normdir = os.path.normcase(dir)
61 | if not normdir in seen:
62 | seen.add(normdir)
63 | for thefile in files:
64 | name = os.path.join(dir, thefile)
65 | if _access_check(name, mode):
66 | return name
67 | return None
68 |
69 |
70 | class PtyProcessError(Exception):
71 | """Generic error class for this package."""
72 |
--------------------------------------------------------------------------------
/manifest.json.in:
--------------------------------------------------------------------------------
1 | {
2 | "name": "waydroidhelper.aaronhafer",
3 | "description": "A collection of tools that help you to use Waydroid.",
4 | "architecture": "@CLICK_ARCH@",
5 | "title": "Waydroid Helper",
6 | "hooks": {
7 | "waydroidhelper": {
8 | "apparmor": "waydroidhelper.apparmor",
9 | "desktop": "waydroidhelper.desktop"
10 | }
11 | },
12 | "version": "3.2.0",
13 | "maintainer": "Aaron Hafer ",
14 | "framework" : "@CLICK_FRAMEWORK@"
15 | }
16 |
--------------------------------------------------------------------------------
/po/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | include(FindGettext)
2 | find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext)
3 |
4 | set(DOMAIN ${FULL_PROJECT_NAME})
5 | set(POT_FILE ${DOMAIN}.pot)
6 | file(GLOB PO_FILES *.po)
7 |
8 | # Creates the .pot file containing the translations template
9 | add_custom_target(${POT_FILE} ALL
10 | COMMENT "Generating translation template"
11 | COMMAND ${INTLTOOL_EXTRACT} --update --type=gettext/ini
12 | --srcdir=${CMAKE_SOURCE_DIR} ${DESKTOP_FILE_NAME}.in
13 |
14 | COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} -o ${POT_FILE}
15 | -D ${CMAKE_CURRENT_SOURCE_DIR}
16 | -D ${CMAKE_CURRENT_BINARY_DIR}
17 | --from-code=UTF-8
18 | --c++ --qt --language=javascript --add-comments=TRANSLATORS
19 | --keyword=tr --keyword=tr:1,2 --keyword=ctr:1c,2 --keyword=dctr:2c,3 --keyword=N_ --keyword=_
20 | --keyword=dtr:2 --keyword=dtr:2,3 --keyword=tag --keyword=tag:1c,2
21 | --package-name='${DOMAIN}'
22 | --sort-by-file
23 | ${I18N_SRC_FILES}
24 | COMMAND ${CMAKE_COMMAND} -E copy ${POT_FILE} ${CMAKE_CURRENT_SOURCE_DIR})
25 |
26 | # Builds the binary translations catalog for each language
27 | # it finds source translations (*.po) for
28 | foreach(PO_FILE ${PO_FILES})
29 | get_filename_component(LANG ${PO_FILE} NAME_WE)
30 | gettext_process_po_files(${LANG} ALL PO_FILES ${PO_FILE})
31 | set(INSTALL_DIR ${CMAKE_INSTALL_LOCALEDIR}/share/locale/${LANG}/LC_MESSAGES)
32 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.gmo
33 | DESTINATION ${INSTALL_DIR}
34 | RENAME ${DOMAIN}.mo)
35 | endforeach(PO_FILE)
36 |
--------------------------------------------------------------------------------
/po/de.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "MIME-Version: 1.0\n"
4 | "Content-Type: text/plain; charset=UTF-8\n"
5 | "Content-Transfer-Encoding: 8bit\n"
6 | "X-Generator: POEditor.com\n"
7 | "Project-Id-Version: WaydroidHelper\n"
8 | "Language: de\n"
9 |
10 | #: ../qml/About.qml:8 ../qml/Main.qml:49
11 | msgid "About"
12 | msgstr "Über"
13 |
14 | #: ../qml/About.qml:32
15 | msgid "WayDroid Helper"
16 | msgstr "WayDroid Helper"
17 |
18 | #: ../qml/About.qml:50
19 | msgid "Version: "
20 | msgstr "Version: "
21 |
22 | #: ../qml/About.qml:58
23 | msgid "A Tweak tool application for WayDroid on Ubuntu Touch."
24 | msgstr "Ein Optimierungswerkzeug für WayDroid auf Ubuntu Touch"
25 |
26 | #. TRANSLATORS: Please make sure the URLs are correct
27 | #: ../qml/About.qml:67
28 | msgid "This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details."
29 | msgstr "Diese Anwendung ist als freie Software herausgegeben: Jeder kann sie selbst veröffentlichen und dabei Veränderungen vornehmen, solang er sich an die Richtlinien der GNU General Public License hält. Diese Richtlinien werden durch die Free Software Stiftung herausgegeben und müssen entwededer Version 3 oder einer (aktuelleren) höheren Version entsprechen. Diese Anwendungen wird veröffentlicht in der Hoffnung, dass sie nützlich ist. Jedoch wird KEINE GARANTIE übernommen - es wird auch nicht garantiert dass diese Anwendung MARKTREIF oder ANGEPASST AUF EINEN ZWECK ist. Weitere Infos hier unter GNU General Public License"
30 |
31 | #: ../qml/About.qml:76
32 | msgid "DONATE"
33 | msgstr "SPENDEN"
34 |
35 | #: ../qml/About.qml:76
36 | msgid "ISSUES"
37 | msgstr "PROBLEME"
38 |
39 | #: ../qml/About.qml:76
40 | msgid "SOURCE"
41 | msgstr "QUELLCODE"
42 |
43 | #: ../qml/About.qml:86
44 | msgid "Copyright"
45 | msgstr "Copyright"
46 |
47 | #: ../qml/About.qml:95
48 | msgid "General contributions: "
49 | msgstr "Allgemeine Teilnahme"
50 |
51 | #: ../qml/Help.qml:13 ../qml/Main.qml:55
52 | msgid "Help"
53 | msgstr "Hilfe"
54 |
55 | #: ../qml/Installer.qml:13
56 | msgid "Install Waydroid"
57 | msgstr "Waydroid installieren"
58 |
59 | #: ../qml/Installer.qml:19
60 | msgid "GAPPS"
61 | msgstr "GAPPS"
62 |
63 | #: ../qml/Installer.qml:48
64 | msgid "By pressing 'start' the installation will, well... start. The installer will let you know what it is doing at the moment. Be patient! The installation may take a while. Do not close the app during the installation! Once Waydroid is installed, your device will restart automatically. I reccomend to disable screen suspension in the settings to keep the screen always on without touching it."
65 | msgstr "Durch Klick auf \"start\" wird die Installation, nunja... starten. Der Installer wird dich wissen lassen was er im Moment tut. Sei Geduldig! Die Installation wird etwas Zeit in Anspruch nehmen. Schließ auf keinen Fall die App während der Installation! Nach der Installation wird das Gerät neustarten. Ich empfehle das automatische Abschalten des Bildschirms in den Systemeinstellungen zu deaktivieren."
66 |
67 | #: ../qml/Installer.qml:58 ../qml/Uninstaller.qml:45
68 | msgid "Start"
69 | msgstr "Start"
70 |
71 | #: ../qml/Installer.qml:73 ../qml/Uninstaller.qml:60
72 | msgid "Running"
73 | msgstr "Läuft"
74 |
75 | #: ../qml/Installer.qml:85
76 | msgid "You are about to use an experimental Waydroid installer! Supported devices (✔️ = tested): * VollaPhone ✔️ (X) * Redmi Note 7 (Pro) * Redmi Note 9 (Pro/Pro Max/S) * Fairphone 3(+) * Pixel 3a There is absolutely no warranty for this to work! Do not use this installer if you dont want to risk to brick your device (,which is highly unlikely though)!"
77 | msgstr "Dieser Installer ist noch experimentell! Unterstützte Geräte (✔️ = getestet): * VollaPhone ✔️ (X) * Redmi Note 7 (Pro) * Redmi Note 9 (Pro/Pro Max/S) * Fairphone 3(+) * Pixel 3a Es gibt keine Garantie, dass die Installation funktioniert! Verwende den Installer nicht, wenn du dein Gerät nicht gefährden willst (auch wenn das sehr unwahrscheinlich ist)!"
78 |
79 | #: ../qml/Installer.qml:90
80 | msgid "I understand the risk"
81 | msgstr "Ich verstehe das Risiko"
82 |
83 | #: ../qml/Installer.qml:95 ../qml/Installer.qml:162
84 | msgid "Cancel"
85 | msgstr "Abbrechen"
86 |
87 | #: ../qml/Installer.qml:114 ../qml/Uninstaller.qml:71
88 | msgid "Enter your password:"
89 | msgstr "Passwort eingeben:"
90 |
91 | #: ../qml/Installer.qml:124 ../qml/Main.qml:160 ../qml/Main.qml:344
92 | #: ../qml/Uninstaller.qml:81
93 | msgid "Ok"
94 | msgstr "Ok"
95 |
96 | #: ../qml/Installer.qml:146
97 | msgid "You can install a special version of Waydroid that comes with google apps. (I personally do not recommend this as it will result in worse privacy.)"
98 | msgstr "Du kannst eine spezielle WayDroid Version installieren, die Google Apps unterstützt (Ich kann das nicht empfehlen, da es die Privatsphäre negativ beeinflusst)"
99 |
100 | #: ../qml/Installer.qml:151
101 | msgid "Enable GAPPS"
102 | msgstr "GAPPS aktivieren"
103 |
104 | #: ../qml/Main.qml:44 waydroidhelper.desktop.in.h:1
105 | msgid "Waydroid Helper"
106 | msgstr "Waydroid Helper"
107 |
108 | #: ../qml/Main.qml:70
109 | msgid "Install Waydroid 📲>"
110 | msgstr "Waydroid Installieren 📲>"
111 |
112 | #: ../qml/Main.qml:83
113 | msgid "Show/Hide apps 🙈>"
114 | msgstr "Apps zeigen/verstecken 🙈>"
115 |
116 | #: ../qml/Main.qml:97
117 | msgid "Waydroid Stop app 🛑>"
118 | msgstr "Waydroid Stop App 🛑>"
119 |
120 | #: ../qml/Main.qml:110
121 | msgid "Waydroid Help ❓>"
122 | msgstr "Waydroid Help ❓>"
123 |
124 | #: ../qml/Main.qml:124
125 | msgid "Uninstall Waydroid 🗑>"
126 | msgstr "Waydroid deinstallieren 🗑>"
127 |
128 | #: ../qml/Main.qml:146
129 | msgid "Show/Hide"
130 | msgstr "Zeigen/Verstecken"
131 |
132 | #: ../qml/Main.qml:154
133 | msgid "Swipe on the listed apps to either hide them(bin) or show them(plus) in the Appdrawer. This will NOT install or uninstall the selected app. Reload the Appdrawer for the changes to take effect."
134 | msgstr "Wische die Einträge in der Liste um sie in der Appübersicht zu verstecken (Mülleimer) oder sie anzuzeigen (plus) Dies wird die Apps NICHT installieren oder deinstallieren. Aktualisiere die Appliste um die Änderungen zu übernehmen."
135 |
136 | #: ../qml/Main.qml:229
137 | msgid "Waydroid Stop"
138 | msgstr "Waydroid Stop"
139 |
140 | #: ../qml/Main.qml:237
141 | msgid "The 'Waydroid Stop app' allows you to easily stop Waydroid without entering the terminal. Once you press 'Add' a new icon will appear in your appdrawer. Pressing this icon will stop Waydroid if it has crashed or anything else went wrong. If you open any of your Android apps, waydroid will start automaticly again."
142 | msgstr "Mit der \"Waydroid Stop App\" kannst Du Waydroid ausschalten ohne das Terminal öffnen zu müssen. Sobald die App über \"hinzufügen\" installiert wurde, wird ein neues Symbol in der Appliste erscheinen. Wenn dieses Symbol gedrückt wird, wird Waydroid gestoppt auch wenn es gecrasht ist. Waydroid startet automatisch wieder, sobald eine Android App gestartet wird."
143 |
144 | #: ../qml/Main.qml:258
145 | msgid "Remove"
146 | msgstr "Entfernen"
147 |
148 | #: ../qml/Main.qml:271
149 | msgid "Add"
150 | msgstr "Hinzufügen"
151 |
152 | #: ../qml/Main.qml:287
153 | msgid "Waydroid Help"
154 | msgstr "Waydroid Help"
155 |
156 | #: ../qml/Main.qml:295
157 | msgid "You need to run these commands in the terminal app. Tap a command to copy it to the clipboard.
"
158 | msgstr "Diese Befehle müssen im Terminal ausgeführt werden. Die Befehle werden in die Zwischenablage kopiert, indem sie angetippt werden.
"
159 |
160 | #: ../qml/Main.qml:315
161 | msgid "waydroid -h, --help show this help message and exit
waydroid -V, --version show program's version number and exit
waydroid -v, --verbose Noch detailiertere Logfiles (Die Performance wird dadurch eventuell verschlechtert)
waydroid -q, --quiet Keine Logs werden geschrieben"
163 |
164 | #: ../qml/Main.qml:339
165 | msgid "You copied a command to your clipboard. You can now paste and use it in the terminal app."
166 | msgstr "Du hast einen Befehl in die Zwischenablage gespeichert. Er kann nun in die Terminal-App eingefügt werden."
167 |
168 | #: ../qml/Uninstaller.qml:14
169 | msgid "Uninstall Waydroid"
170 | msgstr "Waydroid deinstallieren"
171 |
172 | #: ../qml/Uninstaller.qml:35
173 | msgid "Press 'start' to uninstall WayDroid."
174 | msgstr "Drücke \"Start\" um WayDroid zu deinstallieren"
175 |
176 |
--------------------------------------------------------------------------------
/po/fr.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Project-Id-Version: WaydroidHelper\n"
4 | "Report-Msgid-Bugs-To: \n"
5 | "POT-Creation-Date: 2022-02-04 12:11+0000\n"
6 | "PO-Revision-Date: \n"
7 | "Last-Translator: Anne017\n"
8 | "Language-Team: \n"
9 | "Language: fr\n"
10 | "MIME-Version: 1.0\n"
11 | "Content-Type: text/plain; charset=UTF-8\n"
12 | "Content-Transfer-Encoding: 8bit\n"
13 | "X-Generator: Poedit 3.0\n"
14 |
15 | #: ../qml/About.qml:8 ../qml/Main.qml:49
16 | msgid "About"
17 | msgstr "À propos"
18 |
19 | #: ../qml/About.qml:32
20 | msgid "WayDroid Helper"
21 | msgstr "WayDroid Helper"
22 |
23 | #: ../qml/About.qml:50
24 | msgid "Version: "
25 | msgstr "Version :"
26 |
27 | #: ../qml/About.qml:58
28 | msgid "A Tweak tool application for WayDroid on Ubuntu Touch."
29 | msgstr "Un outil de personnalisation pour WayDroid sur Ubuntu Touch."
30 |
31 | #. TRANSLATORS: Please make sure the URLs are correct
32 | #: ../qml/About.qml:67
33 | msgid ""
34 | "This program is free software: you can redistribute it and/or modify it under "
35 | "the terms of the GNU General Public License as published by the Free Software "
36 | "Foundation, either version 3 of the License, or (at your option) any later "
37 | "version. This program is distributed in the hope that it will be useful, but "
38 | "WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or "
39 | "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details."
41 | msgstr ""
42 | "Ce programme est un logiciel libre : vous pouvez le redistribuer et/ou le "
43 | "modifier selon les termes de la licence publique générale GNU telle que "
44 | "publiée par la Free Software Foundation, soit la version 3 de la licence, soit "
45 | "(à votre choix) toute version ultérieure. Ce programme est distribué dans "
46 | "l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ; sans même la garantie "
47 | "implicite de QUALITÉ MARCHANDE ou D'ADAPTATION À UN USAGE PARTICULIER. Voir la "
48 | "Licence publique "
49 | "générale GNU pour plus de détails."
50 |
51 | #: ../qml/About.qml:76
52 | msgid "DONATE"
53 | msgstr "SOUTENIR FINANCIÈREMENT"
54 |
55 | #: ../qml/About.qml:76
56 | msgid "ISSUES"
57 | msgstr "PROBLÈMES"
58 |
59 | #: ../qml/About.qml:76
60 | msgid "SOURCE"
61 | msgstr "SOURCE"
62 |
63 | #: ../qml/About.qml:86
64 | msgid "Copyright"
65 | msgstr "Droits d'auteur"
66 |
67 | #: ../qml/About.qml:95
68 | msgid "General contributions: "
69 | msgstr "Contributions générales"
70 |
71 | #: ../qml/Help.qml:13 ../qml/Main.qml:55
72 | msgid "Help"
73 | msgstr "Aide"
74 |
75 | #: ../qml/Installer.qml:13
76 | msgid "Install Waydroid"
77 | msgstr "Installer WayDroid"
78 |
79 | #: ../qml/Installer.qml:19
80 | msgid "GAPPS"
81 | msgstr "GAPPS (Google Apps)"
82 |
83 | #: ../qml/Installer.qml:48
84 | msgid ""
85 | "By pressing 'start' the installation will, well... start. The installer will "
86 | "let you know what it is doing at the moment. Be patient! The installation may "
87 | "take a while. Do not close the app during the installation! Once Waydroid is "
88 | "installed, your device will restart automatically. I reccomend to disable "
89 | "screen suspension in the settings to keep the screen always on without "
90 | "touching it."
91 | msgstr ""
92 | "En appuyant sur « démarrer » l'installation va débuter. L'installateur vous "
93 | "indiquera l'avancement des opérations. Soyez patient! L'installation peut "
94 | "prendre un certain temps. Ne fermez pas l'application pendant l'installation ! "
95 | "Une fois WayDroid installé, votre appareil redémarrera automatiquement. Il est "
96 | "recommandé de désactiver la suspension de l'écran dans les paramètres pour "
97 | "conserver l'écran toujours allumé sans le toucher. "
98 |
99 | #: ../qml/Installer.qml:58 ../qml/Uninstaller.qml:45
100 | msgid "Start"
101 | msgstr "Démarrer"
102 |
103 | #: ../qml/Installer.qml:73 ../qml/Uninstaller.qml:60
104 | msgid "Running"
105 | msgstr "En cours"
106 |
107 | #: ../qml/Installer.qml:85
108 | msgid ""
109 | "You are about to use an experimental Waydroid installer! Supported "
110 | "devices (✔️ = tested): * VollaPhone ✔️ (X) * Redmi Note 7 (Pro) * "
111 | "Redmi Note (9 Pro/9 Pro Max) * Fairphone 3(+) * Pixel (3a/XL/2 XL) "
112 | " * MI A2 (wifi does not work with GAPPS) * Poco F1 * SHIFT6mq "
113 | " These devices have partial support: * Pixel 3a XL (no video "
114 | "playback) * Pinephone (unstable) * Redmi Note 9 (no external "
115 | "storage) There is absolutely no warranty for this to work! Do not use "
116 | "this installer if you dont want to risk to brick your device (,which is highly "
117 | "unlikely though)!"
118 | msgstr ""
119 | "Vous êtes sur le point d'utiliser un programme d'installation expérimental de "
120 | "WayDroid ! Appareils pris en charge (✔️ = testés) : * VollaPhone ✔️ "
121 | "(X) * Redmi Note 7 (Pro) * Redmi Note 9 (Pro/Pro Max/S) * "
122 | "Fairphone 3(+) ** Pixel (3a/XL/2 XL) * MI A2 (le Wi-Fi ne marche pas "
123 | "avec les GAPPS) * Poco F1 * SHIFT6mq Ces appareils ont une "
124 | "prise en charge partielle : * Pixel 3a XL (pas de lecture vidéo) * "
125 | "Pinephone (instable) * Redmi Note 9 (pas de stockage externe) Il n'y "
126 | "a absolument aucune garantie que cela fonctionne ! N'utilisez pas ce programme "
127 | "d'installation si vous ne voulez pas risquer de détériorer le fonctionnement "
128 | "de votre appareil (ce qui est cependant hautement improbable) ! "
129 |
130 | #: ../qml/Installer.qml:90
131 | msgid "I understand the risk"
132 | msgstr "Je comprends les risques"
133 |
134 | #: ../qml/Installer.qml:95 ../qml/Installer.qml:162
135 | msgid "Cancel"
136 | msgstr "Annuler"
137 |
138 | #: ../qml/Installer.qml:114 ../qml/Uninstaller.qml:71
139 | msgid "Enter your password:"
140 | msgstr "Entrez votre mot de passe :"
141 |
142 | #: ../qml/Installer.qml:124 ../qml/Main.qml:160 ../qml/Main.qml:344
143 | #: ../qml/Uninstaller.qml:81
144 | msgid "Ok"
145 | msgstr "Valider"
146 |
147 | #: ../qml/Installer.qml:146
148 | msgid ""
149 | "You can install a special version of Waydroid that comes with google apps. (I "
150 | "personally do not recommend this as it will result in worse privacy.)"
151 | msgstr ""
152 | "Vous pouvez installer une version spécifique de WayDroid incluant les Google "
153 | "Apps. (Je déconseille toutefois cette version pour des raisons de pertes de "
154 | "confidentialité)."
155 |
156 | #: ../qml/Installer.qml:151
157 | msgid "Enable GAPPS"
158 | msgstr "Activer GAPPS (Google Apps)"
159 |
160 | #: ../qml/Main.qml:44 waydroidhelper.desktop.in.h:1
161 | msgid "Waydroid Helper"
162 | msgstr "WayDroid Helper"
163 |
164 | #: ../qml/Main.qml:70
165 | msgid "Install Waydroid 📲>"
166 | msgstr "Installer WayDroid 📲>"
167 |
168 | #: ../qml/Main.qml:83
169 | msgid "Show/Hide apps 🙈>"
170 | msgstr "Afficher/Masquer les applications 🙈>"
171 |
172 | #: ../qml/Main.qml:97
173 | msgid "Waydroid Stop app 🛑>"
174 | msgstr "Arrêter WayDroid 🛑>"
175 |
176 | #: ../qml/Main.qml:110
177 | msgid "Waydroid Help ❓>"
178 | msgstr "Aide de WayDroid ❓>"
179 |
180 | #: ../qml/Main.qml:124
181 | msgid "Uninstall Waydroid 🗑>"
182 | msgstr "Désinstaller WayDroid 🗑>"
183 |
184 | #: ../qml/Main.qml:146
185 | msgid "Show/Hide"
186 | msgstr "Afficher/Masquer"
187 |
188 | #: ../qml/Main.qml:154
189 | msgid ""
190 | "Swipe on the listed apps to either hide them(bin) or show them(plus) in the "
191 | "Appdrawer. This will NOT install or uninstall the selected app. Reload the "
192 | "Appdrawer for the changes to take effect."
193 | msgstr ""
194 | "Balayez vers la droite les applications répertoriées pour les masquer "
195 | "(poubelle) ou vers la gauche pour les afficher (signe +) dans le lanceur "
196 | "d'applications. Cela n'installera ou ne désinstallera PAS l'application "
197 | "sélectionnée. Rechargez le lanceur d'applications pour que les modifications "
198 | "prennent effet. (Balayez vers le bas)"
199 |
200 | #: ../qml/Main.qml:229
201 | msgid "Waydroid Stop"
202 | msgstr "Arrêter WayDroid"
203 |
204 | #: ../qml/Main.qml:237
205 | msgid ""
206 | "The 'Waydroid Stop app' allows you to easily stop Waydroid without entering "
207 | "the terminal. Once you press 'Add' a new icon will appear in your appdrawer. "
208 | "Pressing this icon will stop Waydroid if it has crashed or anything else went "
209 | "wrong. If you open any of your Android apps, waydroid will start automaticly "
210 | "again."
211 | msgstr ""
212 | "La fonction 'Arrêter WayDroid' vous permet d'arrêter WayDroid sans avoir "
213 | "besoin de vous rendre dans le terminal. Lorsque vous appuyez sur 'ajouter', "
214 | "une nouvelle icône va apparaître dans le lanceur. Appuyez sur cette icône pour "
215 | "arrêter WayDroid en cas de crash ou tout autre dysfonctionnement. En ouvrant "
216 | "n'importe quelle application Android, WayDroid va automatiquement redémarrer."
217 |
218 | #: ../qml/Main.qml:258
219 | msgid "Remove"
220 | msgstr "Enlever"
221 |
222 | #: ../qml/Main.qml:271
223 | msgid "Add"
224 | msgstr "Ajouter"
225 |
226 | #: ../qml/Main.qml:287
227 | msgid "Waydroid Help"
228 | msgstr "Aide de WayDroid"
229 |
230 | #: ../qml/Main.qml:295
231 | msgid ""
232 | "You need to run these commands in the terminal app. Tap a command to copy "
233 | "it to the clipboard.
"
234 | msgstr ""
235 | "Vous devez exécuter ces commandes dans l'application 'terminal'. Appuyez "
236 | "sur une commande pour la copier dans le presse-papiers.
"
237 |
238 | #: ../qml/Main.qml:315
239 | msgid ""
240 | "waydroid -h, --help show this help message and exit "
241 | "
waydroid -V, --version show program's "
242 | "version number and exit
waydroid --details-to-stdout imprime "
255 | "les détails (par exemple, la sortie de construction) sur stdout, au lieu "
256 | "d'écrire dans le journal
< a href='waydroid -v'>waydroid -v, --"
257 | "verbose écrit encore plus dans les fichiers journaux (cela peut réduire les "
258 | "performances)
waydroid - q, --quiet "
259 | "n'affiche aucun message de journal "
260 |
261 | #: ../qml/Main.qml:339
262 | msgid ""
263 | "You copied a command to your clipboard. You can now paste and use it in the "
264 | "terminal app."
265 | msgstr ""
266 | "Vous avez copié une commande dans votre presse-papiers. Vous pouvez maintenant "
267 | "la coller et l'utiliser dans l'application 'terminal'. "
268 |
269 | #: ../qml/Uninstaller.qml:14
270 | msgid "Uninstall Waydroid"
271 | msgstr "Désinstaller WayDroid"
272 |
273 | #: ../qml/Uninstaller.qml:35
274 | msgid "Press 'start' to uninstall WayDroid."
275 | msgstr "Appuyer sur « démarrer » pour désinstaller WayDroid."
276 |
--------------------------------------------------------------------------------
/po/nl.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Project-Id-Version: WaydroidHelper\n"
4 | "Report-Msgid-Bugs-To: \n"
5 | "POT-Creation-Date: 2024-03-27 23:26+0000\n"
6 | "PO-Revision-Date: \n"
7 | "Last-Translator: Heimen Stoffels \n"
8 | "Language-Team: \n"
9 | "Language: nl\n"
10 | "MIME-Version: 1.0\n"
11 | "Content-Type: text/plain; charset=UTF-8\n"
12 | "Content-Transfer-Encoding: 8bit\n"
13 | "X-Generator: Poedit 3.4.2\n"
14 |
15 | #: ../qml/About.qml:8 ../qml/Main.qml:97
16 | msgid "About"
17 | msgstr "Over"
18 |
19 | #: ../qml/About.qml:32
20 | msgid "WayDroid Helper"
21 | msgstr "WayDroid-hulpapp"
22 |
23 | #: ../qml/About.qml:50
24 | msgid "Version: "
25 | msgstr "Versie: "
26 |
27 | #: ../qml/About.qml:58
28 | msgid "A Tweak tool application for WayDroid on Ubuntu Touch."
29 | msgstr "Een app voor het afstellen van Waydroid op Ubuntu Touch."
30 |
31 | #. TRANSLATORS: Please make sure the URLs are correct
32 | #: ../qml/About.qml:67
33 | msgid ""
34 | "This program is free software: you can redistribute it and/or modify it "
35 | "under the terms of the GNU General Public License as published by the Free "
36 | "Software Foundation, either version 3 of the License, or (at your option) "
37 | "any later version. This program is distributed in the hope that it will be "
38 | "useful, but WITHOUT ANY WARRANTY; without even the implied warranty of "
39 | "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public "
41 | "License for more details."
42 | msgstr ""
43 | "Dit programma is vrije software: je mag het heruitgeven en/of wijzigen onder "
44 | "de voorwaarden van de GNU Algemene Publieke Licentie zoals gepubliceerd door "
45 | "de Free Software Foundation, onder versie 3 van de licentie of (naar eigen "
46 | "inzicht) elke latere versie. Dit programma is gedistribueerd in de hoop dat "
47 | "het nuttig zal zijn maar ZONDER ENIGE GARANTIE; zelfs zonder de impliciete "
48 | "garanties die GEBRUIKELIJK ZIJN IN DE HANDEL of voor BRUIKBAARHEID VOOR EEN "
49 | "SPECIFIEK DOEL. Zie de GNU Algemene Publieke Licentie voor meer details."
51 |
52 | #: ../qml/About.qml:76
53 | msgid "DONATE"
54 | msgstr "DONEREN"
55 |
56 | #: ../qml/About.qml:76
57 | msgid "ISSUES"
58 | msgstr "PROBLEMEN"
59 |
60 | #: ../qml/About.qml:76
61 | msgid "SOURCE"
62 | msgstr "BRONCODE"
63 |
64 | #: ../qml/About.qml:86
65 | msgid "Copyright"
66 | msgstr "Copyright"
67 |
68 | #: ../qml/About.qml:95
69 | msgid "General contributions: "
70 | msgstr "Algemene bijdragen: "
71 |
72 | #: ../qml/Installer.qml:12
73 | msgid "Install Waydroid"
74 | msgstr "Waydroid installeren"
75 |
76 | #: ../qml/Installer.qml:19
77 | msgid "GAPPS"
78 | msgstr "GAPPS"
79 |
80 | #: ../qml/Installer.qml:34
81 | msgid ""
82 | "By pressing 'start' the installation will, well... start. The installer will "
83 | "let you know what it is currently doing. The installation might take a "
84 | "while. You can safely use other apps or turn off the screen, but don't close "
85 | "this one."
86 | msgstr ""
87 | "Druk op ‘Starten’ om de installatie - je raadt het al - te starten. De "
88 | "installatiewizard toont de installatiestatus. Maar heb geduld, want het kan "
89 | "even duren. Sluit de app niet af zolang de installatie nog loopt!"
90 |
91 | #: ../qml/Installer.qml:35
92 | msgid "Installation starting"
93 | msgstr "Bezig met starten…"
94 |
95 | #: ../qml/Installer.qml:36
96 | msgid "Preparing to download system image (with GAPPS)"
97 | msgstr "Bezig met voorbereiden van schijfkopie (met GAPPS)…"
98 |
99 | #: ../qml/Installer.qml:37
100 | msgid "Preparing to download system image"
101 | msgstr "Bezig met voorbereiden van schijfkopie…"
102 |
103 | #: ../qml/Installer.qml:38
104 | msgid "Downloading system image (with GAPPS)"
105 | msgstr "Bezig met downloaden van schijfkopie (met GAPPS)…"
106 |
107 | #: ../qml/Installer.qml:39
108 | msgid "Downloading system image"
109 | msgstr "Bezig met downloaden van schijfkopie…"
110 |
111 | #: ../qml/Installer.qml:40
112 | msgid "Downloading vendor image"
113 | msgstr "Bezig met downloaden van fabrikant-schijfkopie…"
114 |
115 | #: ../qml/Installer.qml:41
116 | msgid "Validating system image"
117 | msgstr "Bezig met valideren van schijfkopie…"
118 |
119 | #: ../qml/Installer.qml:42
120 | msgid "Validating vendor image"
121 | msgstr "Bezig met valideren van fabrikant-schijfkopie…"
122 |
123 | #: ../qml/Installer.qml:43
124 | msgid "Extracting system image"
125 | msgstr "Bezig met extraheren van schijfkopie…"
126 |
127 | #: ../qml/Installer.qml:44
128 | msgid "Extracting vendor image"
129 | msgstr "Bezig met extraheren van fabrikant-schijfkopie…"
130 |
131 | #: ../qml/Installer.qml:45
132 | msgid "Installation complete!"
133 | msgstr "De installatie is afgerond!"
134 |
135 | #: ../qml/Installer.qml:143 ../qml/Main.qml:208 ../qml/Main.qml:414
136 | #: ../qml/PasswordPrompt.qml:58 ../qml/Uninstaller.qml:125
137 | msgid "Ok"
138 | msgstr "Oké"
139 |
140 | #: ../qml/Installer.qml:143 ../qml/Uninstaller.qml:125
141 | msgid "Start"
142 | msgstr "Starten"
143 |
144 | #: ../qml/Installer.qml:165
145 | msgid ""
146 | "
There is absolutely no warranty for this to work! Do not use this "
147 | "installer if you dont want to risk to brick your device permenantly (,which "
148 | "is highly unlikely though)!"
149 | msgstr ""
150 | "
Er is geen garantie dat Waydroid werkt! Gebruik de "
151 | "installatiewizard niet als je geen risico wilt lopen om je apparaat te "
152 | "permanent blokkeren (kleine kans, maar toch)!"
153 |
154 | #: ../qml/Installer.qml:165
155 | msgid ""
156 | "You are about to use an experimental Waydroid installer! You can check "
157 | "if your device is supported on https://devices.ubuntu-touch.io"
159 | msgstr ""
160 | "Je staat op het punt gebruik te maken van de experimentele Waydroid-"
161 | "installatiewizard! Je kunt op https://devices.ubuntu-touch.io zien of je apparaat ondersteund "
163 | "wordt."
164 |
165 | #: ../qml/Installer.qml:171
166 | msgid "I understand the risk"
167 | msgstr "Ik begrijp het risico"
168 |
169 | #: ../qml/Installer.qml:177 ../qml/Installer.qml:210 ../qml/Installer.qml:253
170 | #: ../qml/PasswordPrompt.qml:78
171 | msgid "Cancel"
172 | msgstr "Annuleren"
173 |
174 | #: ../qml/Installer.qml:194
175 | msgid ""
176 | "Waydroid doesn't officially support Android versions past 11 (yet). Your "
177 | "device can still run unofficial Android 13 images (with some additional "
178 | "bugs) from https://sourceforge.net/projects/aleasto-"
180 | "lineageos/files/LineageOS 20/waydroid_arm64 which Waydroid Helper can "
181 | "setup (excluding GAPPS).
Do you want to continue?"
182 | msgstr ""
183 | "Waydroid heeft nog geen ondersteuning voor Android-versies hoger dan 11. Je "
184 | "apparaat kan gebruikmaken van Android 13 (met enkele bugs) door middel van "
185 | "https://sourceforge.net/projects/aleasto-lineageos/files/"
187 | "LineageOS 20/waydroid_arm64, welke deze app voor je kan instellen (maar "
188 | "zonder GAPPS).
Wil je doorgaan?"
189 |
190 | #: ../qml/Installer.qml:200
191 | msgid "Yes"
192 | msgstr "Ja"
193 |
194 | #: ../qml/Installer.qml:239
195 | msgid ""
196 | "You can install a special version of Waydroid that comes with google apps. "
197 | "(I personally do not recommend this as it will result in worse privacy.)"
198 | msgstr ""
199 | "Je kunt een speciale versie installeren die standaard de Google-apps aan "
200 | "boord heeft. (niet aanbevolen in verband met Googles privacyproblematiek)"
201 |
202 | #: ../qml/Installer.qml:244
203 | msgid "Enable GAPPS"
204 | msgstr "Google-apps installeren"
205 |
206 | #: ../qml/Main.qml:92 waydroidhelper.desktop.in.h:1
207 | msgid "Waydroid Helper"
208 | msgstr "Waydroid-hulpapp"
209 |
210 | #: ../qml/Main.qml:103
211 | msgid "Help"
212 | msgstr "Hulp"
213 |
214 | #: ../qml/Main.qml:121
215 | msgid "Install Waydroid 📲>"
216 | msgstr "Waydroid installeren 📲>"
217 |
218 | #: ../qml/Main.qml:134
219 | msgid "Show/Hide apps 🙈>"
220 | msgstr "Apps tonen/verbergen 🙈>"
221 |
222 | #: ../qml/Main.qml:148
223 | msgid "Waydroid Stop app 🛑>"
224 | msgstr "App afsluiten 🛑>"
225 |
226 | #: ../qml/Main.qml:161
227 | msgid "Waydroid Help ❓>"
228 | msgstr "Hulppagina ❓>"
229 |
230 | #: ../qml/Main.qml:174
231 | msgid "Uninstall Waydroid 🗑>"
232 | msgstr "Waydroid verwijderen 🗑>"
233 |
234 | #: ../qml/Main.qml:192
235 | msgid "Show/Hide"
236 | msgstr "Tonen/Verbergen"
237 |
238 | #: ../qml/Main.qml:200
239 | msgid "Show/Hide apps"
240 | msgstr "Apps tonen/verbergen"
241 |
242 | #: ../qml/Main.qml:202
243 | msgid ""
244 | "Swipe on the listed apps to either hide them(bin) or show them(plus) in the "
245 | "Appdrawer. This will NOT install or uninstall the selected app. Reload the "
246 | "Appdrawer for the changes to take effect."
247 | msgstr ""
248 | "Veeg over een app om deze te verbergen (prullenbakpictogram) of tonen "
249 | "(pluspictogram) van/op de applijst. De app in kwestie wordt hierdoor NIET "
250 | "geïnstalleerd of verwijderd. Herlaad de applijst om het verschil te zien."
251 |
252 | #: ../qml/Main.qml:283
253 | msgid "Waydroid Stop"
254 | msgstr "WayDroid afbreken"
255 |
256 | #: ../qml/Main.qml:294
257 | msgid ""
258 | "The 'Waydroid Stop app' allows you to easily stop Waydroid without entering "
259 | "the terminal. Once you press 'Add' a new icon will appear in your appdrawer. "
260 | "Pressing this icon will stop Waydroid if it has crashed or anything else "
261 | "went wrong. If you open any of your Android apps, waydroid will start "
262 | "automaticly again."
263 | msgstr ""
264 | "Met de Waydroid-stopapp kun je Waydroid stoppen zonder in de terminal te "
265 | "duiken. Als je op ‘Toevoegen’ drukt, dan wordt er een pictogram getoond op "
266 | "de applijst. Druk hierop om Waydroid te stoppen als gevolg van een crash of "
267 | "een ander probleem. Waydroid wordt opnieuw gestart zodra je één van je "
268 | "Android-apps opent."
269 |
270 | #: ../qml/Main.qml:321
271 | msgid "Remove"
272 | msgstr "Verwijderen"
273 |
274 | #: ../qml/Main.qml:336
275 | msgid "Add"
276 | msgstr "Toevoegen"
277 |
278 | #: ../qml/Main.qml:350
279 | msgid "Waydroid Help"
280 | msgstr "Hulppagina"
281 |
282 | #: ../qml/Main.qml:360
283 | msgid ""
284 | "You need to run these commands in the terminal app. Tap a command to copy "
285 | "it to the clipboard.
"
286 | msgstr ""
287 | "Voer de volgende opdrachten uit in de terminal-app. Druk op een opdracht "
288 | "om deze te kopiëren naar het klembord.
"
289 |
290 | #: ../qml/Main.qml:382
291 | msgid ""
292 | "waydroid -h, --help show this help message and "
293 | "exit
waydroid -V, --version show program's "
294 | "version number and exit
waydroid --details-to-stdout toon gedetailleerde informatie "
307 | "(zoals de compilatie-uitvoer) in stdout i.p.v. in het logboek
waydroid -v, --verbose schrijf gedetailleerde "
309 | "informatie naar het logboek (hierdoor kan prestatieverlies optreden) "
310 | "
waydroid -q, --quiet leg geen logboeken aan"
311 |
312 | #: ../qml/Main.qml:409
313 | msgid ""
314 | "You copied a command to your clipboard. You can now paste and use it in the "
315 | "terminal app."
316 | msgstr ""
317 | "Je hebt een opdracht gekopieerd. Open de terminalapp en plak daar de "
318 | "opdracht."
319 |
320 | #: ../qml/PasswordPrompt.qml:8
321 | msgid "Authorization"
322 | msgstr "Goedkeuring"
323 |
324 | #: ../qml/PasswordPrompt.qml:32
325 | msgid "Enter your passcode:"
326 | msgstr "Voer je toegangscode in:"
327 |
328 | #: ../qml/PasswordPrompt.qml:32
329 | msgid "Enter your password:"
330 | msgstr "Voer je wachtwoord in:"
331 |
332 | #: ../qml/PasswordPrompt.qml:39
333 | msgid "passcode"
334 | msgstr "Toegangscode"
335 |
336 | #: ../qml/PasswordPrompt.qml:39
337 | msgid "password"
338 | msgstr "Wachtwoord"
339 |
340 | #: ../qml/PasswordPrompt.qml:53
341 | msgid "Incorrect passcode"
342 | msgstr "De toegangscode is onjuist"
343 |
344 | #: ../qml/PasswordPrompt.qml:53
345 | msgid "Incorrect password"
346 | msgstr "Het wachtwoord is onjuist"
347 |
348 | #: ../qml/Uninstaller.qml:13
349 | msgid "Uninstall Waydroid"
350 | msgstr "WayDroid verwijderen"
351 |
352 | #: ../qml/Uninstaller.qml:23
353 | msgid "Press 'start' to uninstall Waydroid."
354 | msgstr "Druk op ‘Starten’ om Waydroid te verwijderen."
355 |
356 | #: ../qml/Uninstaller.qml:24
357 | msgid "Uninstallation starting"
358 | msgstr "Bezig met starten van verwijdering…"
359 |
360 | #: ../qml/Uninstaller.qml:25
361 | msgid "Stopping Waydroid container service"
362 | msgstr "Bezig met stoppen van Waydroid-containerdienst…"
363 |
364 | #: ../qml/Uninstaller.qml:26
365 | msgid "Cleaning up Waydroid images"
366 | msgstr "Bezig met opruimen van Waydroid-schijfkopieën…"
367 |
368 | #: ../qml/Uninstaller.qml:27
369 | msgid "Uninstallation complete!"
370 | msgstr "Het verwijderen is voltooid!"
371 |
372 | #: ../qml/Uninstaller.qml:110
373 | msgid "Wipe app data"
374 | msgstr "Appgegevens wissen"
375 |
376 | #~ msgid "Running"
377 | #~ msgstr "Actief"
378 |
379 | #~ msgid ""
380 | #~ "You are about to use an experimental Waydroid installer! Supported "
381 | #~ "devices (✔️ = tested): * VollaPhone ✔️ (X) * Redmi Note 7 (Pro) "
382 | #~ " * Redmi Note 9 (Pro/Pro Max/S) * Fairphone 3(+) * Pixel 3a "
383 | #~ " There is absolutely no warranty for this to work! Do not use this "
384 | #~ "installer if you dont want to risk to brick your device (,which is highly "
385 | #~ "unlikely though)!"
386 | #~ msgstr ""
387 | #~ "Je staat op het punt om de experimentele WayDroid-installatiewizard te "
388 | #~ "starten! Ondersteunde apparaten (✔️ = getest): * VollaPhone ✔️ "
389 | #~ "(X) * Redmi Note 7 (Pro) * Redmi Note 9 (Pro/Pro Max/S) * "
390 | #~ "Fairphone 3(+) * Pixel 3a Er is echter geen garantie dat "
391 | #~ "WayDroid gaat werken! Gebruik de installatiewizard NIET als je bang bent "
392 | #~ "voor een gebrickt apparaat (hoewel de kans heel erg klein is)!"
393 |
--------------------------------------------------------------------------------
/po/pt_PT.po:
--------------------------------------------------------------------------------
1 | # SOME DESCRIPTIVE TITLE.
2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3 | # This file is distributed under the same license as the waydroidhelper.aaronhafer package.
4 | # FIRST AUTHOR , YEAR.
5 | #
6 | #, fuzzy
7 | msgid ""
8 | msgstr ""
9 | "Project-Id-Version: waydroidhelper.aaronhafer\n"
10 | "Report-Msgid-Bugs-To: \n"
11 | "POT-Creation-Date: 2023-04-07 08:47+0000\n"
12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 | "Last-Translator: Ivo Xavier \n"
14 | "Language-Team: LANGUAGE \n"
15 | "Language: pt\n"
16 | "MIME-Version: 1.0\n"
17 | "Content-Type: text/plain; charset=UTF-8\n"
18 | "Content-Transfer-Encoding: 8bit\n"
19 |
20 | #: ../qml/About.qml:8 ../qml/Main.qml:97
21 | msgid "About"
22 | msgstr "Acerca"
23 |
24 | #: ../qml/About.qml:32
25 | msgid "WayDroid Helper"
26 | msgstr "WayDroid Helper"
27 |
28 | #: ../qml/About.qml:50
29 | msgid "Version: "
30 | msgstr "Versão:"
31 |
32 | #: ../qml/About.qml:58
33 | msgid "A Tweak tool application for WayDroid on Ubuntu Touch."
34 | msgstr "Uma aplicação de ajustes de WayDroid para Ubuntu Touch."
35 |
36 | #. TRANSLATORS: Please make sure the URLs are correct
37 | #: ../qml/About.qml:67
38 | msgid ""
39 | "This program is free software: you can redistribute it and/or modify it "
40 | "under the terms of the GNU General Public License as published by the Free "
41 | "Software Foundation, either version 3 of the License, or (at your option) "
42 | "any later version. This program is distributed in the hope that it will be "
43 | "useful, but WITHOUT ANY WARRANTY; without even the implied warranty of "
44 | "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public "
46 | "License for more details."
47 | msgstr ""
48 |
49 | #: ../qml/About.qml:76
50 | msgid "DONATE"
51 | msgstr "DOAR"
52 |
53 | #: ../qml/About.qml:76
54 | msgid "ISSUES"
55 | msgstr "PROBLEMAS"
56 |
57 | #: ../qml/About.qml:76
58 | msgid "SOURCE"
59 | msgstr "CÓDIGO-FONTE"
60 |
61 | #: ../qml/About.qml:86
62 | msgid "Copyright"
63 | msgstr "Direitos de autor"
64 |
65 | #: ../qml/About.qml:95
66 | msgid "General contributions: "
67 | msgstr "Contribuições Gerais"
68 |
69 | #: ../qml/Installer.qml:12
70 | msgid "Install Waydroid"
71 | msgstr "Instalar WayDroid"
72 |
73 | #: ../qml/Installer.qml:18
74 | msgid "GAPPS"
75 | msgstr "GAPPS"
76 |
77 | #: ../qml/Installer.qml:32
78 | msgid ""
79 | "By pressing 'start' the installation will, well... start. The installer will "
80 | "let you know what it is currently doing. The installation might take a "
81 | "while. You can safely use other apps or turn off the screen, but don't close "
82 | "this one."
83 | msgstr ""
84 | "Ao pressionar 'iniciar' a instalação inicia. O instalador irá "
85 | "avisá-lo sobre o que está a ser feito. A instalação vai demorar "
86 | "um pouco. Você pode usar outras apps ou desligar o ecrã, mas não encerre "
87 | "o WayDroid Helper."
88 |
89 | #: ../qml/Installer.qml:33
90 | msgid "Installation starting"
91 | msgstr "Instalação a iniciar"
92 |
93 | #: ../qml/Installer.qml:34
94 | msgid "Preparing to download system image (with GAPPS)"
95 | msgstr "A preparar para transferir a imagem de sistema (com GAPPS)"
96 |
97 | #: ../qml/Installer.qml:35
98 | msgid "Preparing to download system image"
99 | msgstr "A preprar para transferir a imagem de sistema"
100 |
101 | #: ../qml/Installer.qml:36
102 | msgid "Downloading system image (with GAPPS)"
103 | msgstr "A transferir a imagem de sistema (com GAPPS)"
104 |
105 | #: ../qml/Installer.qml:37
106 | msgid "Downloading system image"
107 | msgstr "A transferir a imagem de sistema"
108 |
109 | #: ../qml/Installer.qml:38
110 | msgid "Downloading vendor image"
111 | msgstr "A transferir a imagem do fabricante"
112 |
113 | #: ../qml/Installer.qml:39
114 | msgid "Validating system image"
115 | msgstr "A validar o sistema de imagem"
116 |
117 | #: ../qml/Installer.qml:40
118 | msgid "Validating vendor image"
119 | msgstr "A validar a imagem do fabricante"
120 |
121 | #: ../qml/Installer.qml:41
122 | msgid "Extracting system image"
123 | msgstr "A extrair a imagem do sistema"
124 |
125 | #: ../qml/Installer.qml:42
126 | msgid "Extracting vendor image"
127 | msgstr "A extrair a imagem do fabricante"
128 |
129 | #: ../qml/Installer.qml:43
130 | msgid "Installation complete!"
131 | msgstr "Instalação completa!"
132 |
133 | #: ../qml/Installer.qml:134 ../qml/Main.qml:208 ../qml/Main.qml:414
134 | #: ../qml/PasswordPrompt.qml:58 ../qml/Uninstaller.qml:125
135 | msgid "Ok"
136 | msgstr "Ok"
137 |
138 | #: ../qml/Installer.qml:134 ../qml/Uninstaller.qml:125
139 | msgid "Start"
140 | msgstr "Iniciar"
141 |
142 | #: ../qml/Installer.qml:156
143 | msgid ""
144 | " Fairphone 3/3 OnePlus 5/5T OnePlus 6/6T Pixel/Pixel "
145 | "XL Pixel 2 XL Pixel 3a Poco F1 Redmi Note 7/7 Pro/9 Pro/9 Pro "
146 | "Max Samsung Galaxy S10 SHIFT6mq Vollaphone (X) "
147 | msgstr ""
148 |
149 | #: ../qml/Installer.qml:156
150 | msgid ""
151 | "Other devices using Halium 9 or above may or may not work as well! "
152 | "There is absolutely no warranty for this to work! Do not use this installer "
153 | "if you dont want to risk to brick your device permenantly (,which is highly "
154 | "unlikely though)!"
155 | msgstr ""
156 | "Outros dispositivos com Halium 9 ou acima podem ou não funcionar! "
157 | "Não existe garantia absoluta que isto funcionará! Não utilize o WayDroid Helper "
158 | "se não pretender bloquear o seu dispositivo (sendo, contudo, "
159 | "pouco provável)!"
160 |
161 | #: ../qml/Installer.qml:156
162 | msgid ""
163 | "You are about to use an experimental Waydroid installer! Supported "
164 | "devices:"
165 | msgstr ""
166 | "Está prestes a utilizar um instalador experimental do WayDroid! Dispositivos "
167 | "suportados:"
168 |
169 | #: ../qml/Installer.qml:161
170 | msgid "I understand the risk"
171 | msgstr "Eu entendo o risco"
172 |
173 | #: ../qml/Installer.qml:167 ../qml/Installer.qml:210
174 | #: ../qml/PasswordPrompt.qml:78
175 | msgid "Cancel"
176 | msgstr "Cancelar"
177 |
178 | #: ../qml/Installer.qml:196
179 | msgid ""
180 | "You can install a special version of Waydroid that comes with google apps. "
181 | "(I personally do not recommend this as it will result in worse privacy.)"
182 | msgstr ""
183 | "Você pode instalar uma versão especial do WayDroid que tem as google apps. "
184 | "(Pessoalmente, não recomendo pois resulta em pior privacidade.)"
185 | #: ../qml/Installer.qml:201
186 | msgid "Enable GAPPS"
187 | msgstr "Ativar GAPPS"
188 |
189 | #: ../qml/Main.qml:92 waydroidhelper.desktop.in.h:1
190 | msgid "Waydroid Helper"
191 | msgstr "WayDroid Helper"
192 |
193 | #: ../qml/Main.qml:103
194 | msgid "Help"
195 | msgstr "Ajudar"
196 |
197 | #: ../qml/Main.qml:121
198 | msgid "Install Waydroid 📲>"
199 | msgstr "Instalar WayDroid 📲>"
200 |
201 | #: ../qml/Main.qml:134
202 | msgid "Show/Hide apps 🙈>"
203 | msgstr "Mostrar/Ocultar apps 🙈>"
204 |
205 | #: ../qml/Main.qml:148
206 | msgid "Waydroid Stop app 🛑>"
207 | msgstr "Parar WayDroid App 🛑>"
208 |
209 | #: ../qml/Main.qml:161
210 | msgid "Waydroid Help ❓>"
211 | msgstr "Ajuda Waydroid ❓>"
212 |
213 | #: ../qml/Main.qml:200
214 | msgid "Show/Hide apps"
215 | msgstr "Mostrar/Ocultar apps"
216 |
217 | #: ../qml/Main.qml:174
218 | msgid "Uninstall Waydroid 🗑>"
219 | msgstr "Desinstalar WayDroid 🗑>"
220 |
221 | #: ../qml/Main.qml:192
222 | msgid "Show/Hide"
223 | msgstr "Mostrar/Ocultar"
224 |
225 | #: ../qml/Main.qml:202
226 | msgid ""
227 | "Swipe on the listed apps to either hide them(bin) or show them(plus) in the "
228 | "Appdrawer. This will NOT install or uninstall the selected app. Reload the "
229 | "Appdrawer for the changes to take effect."
230 | msgstr ""
231 | "Deslize nas aplicações listadas para ocultá-las(bin) ou mostrá-las (mais) no "
232 | "Appdrawer. Isso NÃO instalará ou desinstalará a aplicação selecionada. Recarregue o "
233 | "Appdrawer para que as alterações entrem em vigor."
234 |
235 | #: ../qml/Main.qml:283
236 | msgid "Waydroid Stop"
237 | msgstr "Parar WayDroid"
238 |
239 | #: ../qml/Main.qml:294
240 | msgid ""
241 | "The 'Waydroid Stop app' allows you to easily stop Waydroid without entering "
242 | "the terminal. Once you press 'Add' a new icon will appear in your appdrawer. "
243 | "Pressing this icon will stop Waydroid if it has crashed or anything else "
244 | "went wrong. If you open any of your Android apps, waydroid will start "
245 | "automaticly again."
246 | msgstr ""
247 | "A aplicação 'Waydroid Stop' permite que você pare facilmente o WayDroid sem utilizar "
248 | "o terminal. Depois de pressionar 'Adicionar', um novo ícone aparecerá no AppDrawer. "
249 | "Pressionar este ícone irá parar o WayDroid se ele travar ou se qualquer outra coisa"
250 | "deu errado. Se você abrir qualquer um dos seus aplicativos Android, o WayDroid iniciará "
251 | "automaticamente de novo."
252 |
253 | #: ../qml/Main.qml:321
254 | msgid "Remove"
255 | msgstr "Remover"
256 |
257 | #: ../qml/Main.qml:336
258 | msgid "Add"
259 | msgstr "Adicionar"
260 |
261 | #: ../qml/Main.qml:350
262 | msgid "Waydroid Help"
263 | msgstr "Ajuda WayDroid"
264 |
265 | #: ../qml/Main.qml:360
266 | msgid ""
267 | "You need to run these commands in the terminal app. Tap a command to copy "
268 | "it to the clipboard.
"
269 | msgstr ""
270 | "Você precisa de executar estes comandos na app do terminal. Clique num comando para copiar "
271 | "para a área de transferências.
"
272 |
273 | #: ../qml/Main.qml:382
274 | msgid ""
275 | "waydroid -h, --help show this help message and "
276 | "exit
waydroid -V, --version show program's "
277 | "version number and exit
waydroid --details-to-stdout print details (e.g. build output) "
280 | "to stdout, instead of writing to the log
waydroid -v, --verbose write even more to the logfiles (this may "
282 | "reduce performance)
waydroid -q, --quiet "
283 | "do not output any log messages"
284 | msgstr ""
285 |
286 | #: ../qml/Main.qml:409
287 | msgid ""
288 | "You copied a command to your clipboard. You can now paste and use it in the "
289 | "terminal app."
290 | msgstr ""
291 | "Você copiou um comando para a área de transferências. Você pode agora colar e usar na "
292 | "app do terminal."
293 |
294 | #: ../qml/PasswordPrompt.qml:8
295 | msgid "Authorization"
296 | msgstr "Autorização"
297 |
298 | #: ../qml/PasswordPrompt.qml:32
299 | msgid "Enter your passcode:"
300 | msgstr "Introduza o seu código:"
301 |
302 | #: ../qml/PasswordPrompt.qml:32
303 | msgid "Enter your password:"
304 | msgstr "Introduza a sua palavra-passe"
305 |
306 | #: ../qml/PasswordPrompt.qml:39
307 | msgid "passcode"
308 | msgstr "código"
309 |
310 | #: ../qml/PasswordPrompt.qml:39
311 | msgid "password"
312 | msgstr "palavra-passe"
313 |
314 | #: ../qml/PasswordPrompt.qml:53
315 | msgid "Incorrect passcode"
316 | msgstr "Código incorreto"
317 |
318 | #: ../qml/PasswordPrompt.qml:53
319 | msgid "Incorrect password"
320 | msgstr "Palavra-passe incorreta"
321 |
322 | #: ../qml/Uninstaller.qml:13
323 | msgid "Uninstall Waydroid"
324 | msgstr "Desinstalar WayDroid"
325 |
326 | #: ../qml/Uninstaller.qml:23
327 | msgid "Press 'start' to uninstall Waydroid."
328 | msgstr "Pressione 'iniciar' para desinstalar o WayDroid"
329 |
330 | #: ../qml/Uninstaller.qml:24
331 | msgid "Uninstallation starting"
332 | msgstr "A inicar desistalação"
333 |
334 | #: ../qml/Uninstaller.qml:25
335 | msgid "Stopping Waydroid container service"
336 | msgstr "A parar o serviço de container do WayDroid"
337 |
338 | #: ../qml/Uninstaller.qml:26
339 | msgid "Cleaning up Waydroid images"
340 | msgstr "A limpar as imagens do WayDroid"
341 |
342 | #: ../qml/Uninstaller.qml:27
343 | msgid "Uninstallation complete!"
344 | msgstr "Desinstalação completa!"
345 |
346 | #: ../qml/Uninstaller.qml:110
347 | msgid "Wipe app data"
348 | msgstr "Limpar dados da app"
349 |
--------------------------------------------------------------------------------
/po/waydroidhelper.aaronhafer.pot:
--------------------------------------------------------------------------------
1 | # SOME DESCRIPTIVE TITLE.
2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3 | # This file is distributed under the same license as the waydroidhelper.aaronhafer package.
4 | # FIRST AUTHOR , YEAR.
5 | #
6 | #, fuzzy
7 | msgid ""
8 | msgstr ""
9 | "Project-Id-Version: waydroidhelper.aaronhafer\n"
10 | "Report-Msgid-Bugs-To: \n"
11 | "POT-Creation-Date: 2024-03-27 23:26+0000\n"
12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 | "Last-Translator: FULL NAME \n"
14 | "Language-Team: LANGUAGE \n"
15 | "Language: \n"
16 | "MIME-Version: 1.0\n"
17 | "Content-Type: text/plain; charset=UTF-8\n"
18 | "Content-Transfer-Encoding: 8bit\n"
19 |
20 | #: ../qml/About.qml:8 ../qml/Main.qml:97
21 | msgid "About"
22 | msgstr ""
23 |
24 | #: ../qml/About.qml:32
25 | msgid "WayDroid Helper"
26 | msgstr ""
27 |
28 | #: ../qml/About.qml:50
29 | msgid "Version: "
30 | msgstr ""
31 |
32 | #: ../qml/About.qml:58
33 | msgid "A Tweak tool application for WayDroid on Ubuntu Touch."
34 | msgstr ""
35 |
36 | #. TRANSLATORS: Please make sure the URLs are correct
37 | #: ../qml/About.qml:67
38 | msgid ""
39 | "This program is free software: you can redistribute it and/or modify it "
40 | "under the terms of the GNU General Public License as published by the Free "
41 | "Software Foundation, either version 3 of the License, or (at your option) "
42 | "any later version. This program is distributed in the hope that it will be "
43 | "useful, but WITHOUT ANY WARRANTY; without even the implied warranty of "
44 | "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public "
46 | "License for more details."
47 | msgstr ""
48 |
49 | #: ../qml/About.qml:76
50 | msgid "DONATE"
51 | msgstr ""
52 |
53 | #: ../qml/About.qml:76
54 | msgid "ISSUES"
55 | msgstr ""
56 |
57 | #: ../qml/About.qml:76
58 | msgid "SOURCE"
59 | msgstr ""
60 |
61 | #: ../qml/About.qml:86
62 | msgid "Copyright"
63 | msgstr ""
64 |
65 | #: ../qml/About.qml:95
66 | msgid "General contributions: "
67 | msgstr ""
68 |
69 | #: ../qml/Installer.qml:12
70 | msgid "Install Waydroid"
71 | msgstr ""
72 |
73 | #: ../qml/Installer.qml:19
74 | msgid "GAPPS"
75 | msgstr ""
76 |
77 | #: ../qml/Installer.qml:34
78 | msgid ""
79 | "By pressing 'start' the installation will, well... start. The installer will "
80 | "let you know what it is currently doing. The installation might take a "
81 | "while. You can safely use other apps or turn off the screen, but don't close "
82 | "this one."
83 | msgstr ""
84 |
85 | #: ../qml/Installer.qml:35
86 | msgid "Installation starting"
87 | msgstr ""
88 |
89 | #: ../qml/Installer.qml:36
90 | msgid "Preparing to download system image (with GAPPS)"
91 | msgstr ""
92 |
93 | #: ../qml/Installer.qml:37
94 | msgid "Preparing to download system image"
95 | msgstr ""
96 |
97 | #: ../qml/Installer.qml:38
98 | msgid "Downloading system image (with GAPPS)"
99 | msgstr ""
100 |
101 | #: ../qml/Installer.qml:39
102 | msgid "Downloading system image"
103 | msgstr ""
104 |
105 | #: ../qml/Installer.qml:40
106 | msgid "Downloading vendor image"
107 | msgstr ""
108 |
109 | #: ../qml/Installer.qml:41
110 | msgid "Validating system image"
111 | msgstr ""
112 |
113 | #: ../qml/Installer.qml:42
114 | msgid "Validating vendor image"
115 | msgstr ""
116 |
117 | #: ../qml/Installer.qml:43
118 | msgid "Extracting system image"
119 | msgstr ""
120 |
121 | #: ../qml/Installer.qml:44
122 | msgid "Extracting vendor image"
123 | msgstr ""
124 |
125 | #: ../qml/Installer.qml:45
126 | msgid "Installation complete!"
127 | msgstr ""
128 |
129 | #: ../qml/Installer.qml:143 ../qml/Main.qml:208 ../qml/Main.qml:414
130 | #: ../qml/PasswordPrompt.qml:58 ../qml/Uninstaller.qml:125
131 | msgid "Ok"
132 | msgstr ""
133 |
134 | #: ../qml/Installer.qml:143 ../qml/Uninstaller.qml:125
135 | msgid "Start"
136 | msgstr ""
137 |
138 | #: ../qml/Installer.qml:165
139 | msgid ""
140 | "
There is absolutely no warranty for this to work! Do not use this "
141 | "installer if you dont want to risk to brick your device permenantly (,which "
142 | "is highly unlikely though)!"
143 | msgstr ""
144 |
145 | #: ../qml/Installer.qml:165
146 | msgid ""
147 | "You are about to use an experimental Waydroid installer! You can check "
148 | "if your device is supported on https://devices.ubuntu-touch.io"
150 | msgstr ""
151 |
152 | #: ../qml/Installer.qml:171
153 | msgid "I understand the risk"
154 | msgstr ""
155 |
156 | #: ../qml/Installer.qml:177 ../qml/Installer.qml:210 ../qml/Installer.qml:253
157 | #: ../qml/PasswordPrompt.qml:78
158 | msgid "Cancel"
159 | msgstr ""
160 |
161 | #: ../qml/Installer.qml:194
162 | msgid ""
163 | "Waydroid doesn't officially support Android versions past 11 (yet). Your "
164 | "device can still run unofficial Android 13 images (with some additional "
165 | "bugs) from https://sourceforge.net/projects/aleasto-"
167 | "lineageos/files/LineageOS 20/waydroid_arm64 which Waydroid Helper can "
168 | "setup (excluding GAPPS).
Do you want to continue?"
169 | msgstr ""
170 |
171 | #: ../qml/Installer.qml:200
172 | msgid "Yes"
173 | msgstr ""
174 |
175 | #: ../qml/Installer.qml:239
176 | msgid ""
177 | "You can install a special version of Waydroid that comes with google apps. "
178 | "(I personally do not recommend this as it will result in worse privacy.)"
179 | msgstr ""
180 |
181 | #: ../qml/Installer.qml:244
182 | msgid "Enable GAPPS"
183 | msgstr ""
184 |
185 | #: ../qml/Main.qml:92 waydroidhelper.desktop.in.h:1
186 | msgid "Waydroid Helper"
187 | msgstr ""
188 |
189 | #: ../qml/Main.qml:103
190 | msgid "Help"
191 | msgstr ""
192 |
193 | #: ../qml/Main.qml:121
194 | msgid "Install Waydroid 📲>"
195 | msgstr ""
196 |
197 | #: ../qml/Main.qml:134
198 | msgid "Show/Hide apps 🙈>"
199 | msgstr ""
200 |
201 | #: ../qml/Main.qml:148
202 | msgid "Waydroid Stop app 🛑>"
203 | msgstr ""
204 |
205 | #: ../qml/Main.qml:161
206 | msgid "Waydroid Help ❓>"
207 | msgstr ""
208 |
209 | #: ../qml/Main.qml:174
210 | msgid "Uninstall Waydroid 🗑>"
211 | msgstr ""
212 |
213 | #: ../qml/Main.qml:192
214 | msgid "Show/Hide"
215 | msgstr ""
216 |
217 | #: ../qml/Main.qml:200
218 | msgid "Show/Hide apps"
219 | msgstr ""
220 |
221 | #: ../qml/Main.qml:202
222 | msgid ""
223 | "Swipe on the listed apps to either hide them(bin) or show them(plus) in the "
224 | "Appdrawer. This will NOT install or uninstall the selected app. Reload the "
225 | "Appdrawer for the changes to take effect."
226 | msgstr ""
227 |
228 | #: ../qml/Main.qml:283
229 | msgid "Waydroid Stop"
230 | msgstr ""
231 |
232 | #: ../qml/Main.qml:294
233 | msgid ""
234 | "The 'Waydroid Stop app' allows you to easily stop Waydroid without entering "
235 | "the terminal. Once you press 'Add' a new icon will appear in your appdrawer. "
236 | "Pressing this icon will stop Waydroid if it has crashed or anything else "
237 | "went wrong. If you open any of your Android apps, waydroid will start "
238 | "automaticly again."
239 | msgstr ""
240 |
241 | #: ../qml/Main.qml:321
242 | msgid "Remove"
243 | msgstr ""
244 |
245 | #: ../qml/Main.qml:336
246 | msgid "Add"
247 | msgstr ""
248 |
249 | #: ../qml/Main.qml:350
250 | msgid "Waydroid Help"
251 | msgstr ""
252 |
253 | #: ../qml/Main.qml:360
254 | msgid ""
255 | "You need to run these commands in the terminal app. Tap a command to copy "
256 | "it to the clipboard.
"
257 | msgstr ""
258 |
259 | #: ../qml/Main.qml:382
260 | msgid ""
261 | "waydroid -h, --help show this help message and "
262 | "exit
waydroid -V, --version show program's "
263 | "version number and exit